diff options
author | Chocobozzz <me@florianbigard.com> | 2020-01-09 09:26:59 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2020-01-09 09:27:21 +0100 |
commit | 6b0c3c7ca917ad09a011c2821f5bd1a2485aebca (patch) | |
tree | a660791ddc78c95fe69469bd7c33e0e719fba871 | |
parent | 119b16e5acffff1901f23c7a0188c78272453e7d (diff) | |
download | PeerTube-6b0c3c7ca917ad09a011c2821f5bd1a2485aebca.tar.gz PeerTube-6b0c3c7ca917ad09a011c2821f5bd1a2485aebca.tar.zst PeerTube-6b0c3c7ca917ad09a011c2821f5bd1a2485aebca.zip |
Optimize list my playlists SQL query
-rw-r--r-- | client/src/app/shared/video-playlist/video-playlist.service.ts | 13 | ||||
-rw-r--r-- | server/controllers/api/accounts.ts | 6 | ||||
-rw-r--r-- | server/models/video/video-playlist.ts | 40 |
3 files changed, 36 insertions, 23 deletions
diff --git a/client/src/app/shared/video-playlist/video-playlist.service.ts b/client/src/app/shared/video-playlist/video-playlist.service.ts index 1ec9315ef..078bcc5d7 100644 --- a/client/src/app/shared/video-playlist/video-playlist.service.ts +++ b/client/src/app/shared/video-playlist/video-playlist.service.ts | |||
@@ -42,6 +42,7 @@ export class VideoPlaylistService { | |||
42 | private videoExistsCache: { [ id: number ]: VideoExistInPlaylist[] } = {} | 42 | private videoExistsCache: { [ id: number ]: VideoExistInPlaylist[] } = {} |
43 | 43 | ||
44 | private myAccountPlaylistCache: ResultList<CachedPlaylist> = undefined | 44 | private myAccountPlaylistCache: ResultList<CachedPlaylist> = undefined |
45 | private myAccountPlaylistCacheRunning = false | ||
45 | private myAccountPlaylistCacheSubject = new Subject<ResultList<CachedPlaylist>>() | 46 | private myAccountPlaylistCacheSubject = new Subject<ResultList<CachedPlaylist>>() |
46 | 47 | ||
47 | constructor ( | 48 | constructor ( |
@@ -78,12 +79,20 @@ export class VideoPlaylistService { | |||
78 | } | 79 | } |
79 | 80 | ||
80 | listMyPlaylistWithCache (user: AuthUser, search?: string) { | 81 | listMyPlaylistWithCache (user: AuthUser, search?: string) { |
81 | if (!search && this.myAccountPlaylistCache) return of(this.myAccountPlaylistCache) | 82 | if (!search) { |
83 | if (this.myAccountPlaylistCacheRunning) return | ||
84 | if (this.myAccountPlaylistCache) return of(this.myAccountPlaylistCache) | ||
85 | } | ||
86 | |||
87 | this.myAccountPlaylistCacheRunning = true | ||
82 | 88 | ||
83 | return this.listAccountPlaylists(user.account, undefined, '-updatedAt', search) | 89 | return this.listAccountPlaylists(user.account, undefined, '-updatedAt', search) |
84 | .pipe( | 90 | .pipe( |
85 | tap(result => { | 91 | tap(result => { |
86 | if (!search) this.myAccountPlaylistCache = result | 92 | if (!search) { |
93 | this.myAccountPlaylistCacheRunning = false | ||
94 | this.myAccountPlaylistCache = result | ||
95 | } | ||
87 | }) | 96 | }) |
88 | ) | 97 | ) |
89 | } | 98 | } |
diff --git a/server/controllers/api/accounts.ts b/server/controllers/api/accounts.ts index 00148ff55..05740318e 100644 --- a/server/controllers/api/accounts.ts +++ b/server/controllers/api/accounts.ts | |||
@@ -133,9 +133,9 @@ async function listAccountPlaylists (req: express.Request, res: express.Response | |||
133 | const serverActor = await getServerActor() | 133 | const serverActor = await getServerActor() |
134 | 134 | ||
135 | // Allow users to see their private/unlisted video playlists | 135 | // Allow users to see their private/unlisted video playlists |
136 | let privateAndUnlisted = false | 136 | let listMyPlaylists = false |
137 | if (res.locals.oauth && res.locals.oauth.token.User.Account.id === res.locals.account.id) { | 137 | if (res.locals.oauth && res.locals.oauth.token.User.Account.id === res.locals.account.id) { |
138 | privateAndUnlisted = true | 138 | listMyPlaylists = true |
139 | } | 139 | } |
140 | 140 | ||
141 | const resultList = await VideoPlaylistModel.listForApi({ | 141 | const resultList = await VideoPlaylistModel.listForApi({ |
@@ -145,7 +145,7 @@ async function listAccountPlaylists (req: express.Request, res: express.Response | |||
145 | count: req.query.count, | 145 | count: req.query.count, |
146 | sort: req.query.sort, | 146 | sort: req.query.sort, |
147 | accountId: res.locals.account.id, | 147 | accountId: res.locals.account.id, |
148 | privateAndUnlisted, | 148 | listMyPlaylists, |
149 | type: req.query.playlistType | 149 | type: req.query.playlistType |
150 | }) | 150 | }) |
151 | 151 | ||
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts index 71a580249..bcdda36e5 100644 --- a/server/models/video/video-playlist.ts +++ b/server/models/video/video-playlist.ts | |||
@@ -68,7 +68,7 @@ type AvailableForListOptions = { | |||
68 | type?: VideoPlaylistType | 68 | type?: VideoPlaylistType |
69 | accountId?: number | 69 | accountId?: number |
70 | videoChannelId?: number | 70 | videoChannelId?: number |
71 | privateAndUnlisted?: boolean, | 71 | listMyPlaylists?: boolean, |
72 | search?: string | 72 | search?: string |
73 | } | 73 | } |
74 | 74 | ||
@@ -124,27 +124,31 @@ type AvailableForListOptions = { | |||
124 | ] | 124 | ] |
125 | }, | 125 | }, |
126 | [ ScopeNames.AVAILABLE_FOR_LIST ]: (options: AvailableForListOptions) => { | 126 | [ ScopeNames.AVAILABLE_FOR_LIST ]: (options: AvailableForListOptions) => { |
127 | // Only list local playlists OR playlists that are on an instance followed by actorId | 127 | |
128 | const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId) | 128 | let whereActor: WhereOptions = {} |
129 | const whereActor = { | ||
130 | [ Op.or ]: [ | ||
131 | { | ||
132 | serverId: null | ||
133 | }, | ||
134 | { | ||
135 | serverId: { | ||
136 | [ Op.in ]: literal(inQueryInstanceFollow) | ||
137 | } | ||
138 | } | ||
139 | ] | ||
140 | } | ||
141 | 129 | ||
142 | const whereAnd: WhereOptions[] = [] | 130 | const whereAnd: WhereOptions[] = [] |
143 | 131 | ||
144 | if (options.privateAndUnlisted !== true) { | 132 | if (options.listMyPlaylists !== true) { |
145 | whereAnd.push({ | 133 | whereAnd.push({ |
146 | privacy: VideoPlaylistPrivacy.PUBLIC | 134 | privacy: VideoPlaylistPrivacy.PUBLIC |
147 | }) | 135 | }) |
136 | |||
137 | // Only list local playlists OR playlists that are on an instance followed by actorId | ||
138 | const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId) | ||
139 | |||
140 | whereActor = { | ||
141 | [ Op.or ]: [ | ||
142 | { | ||
143 | serverId: null | ||
144 | }, | ||
145 | { | ||
146 | serverId: { | ||
147 | [ Op.in ]: literal(inQueryInstanceFollow) | ||
148 | } | ||
149 | } | ||
150 | ] | ||
151 | } | ||
148 | } | 152 | } |
149 | 153 | ||
150 | if (options.accountId) { | 154 | if (options.accountId) { |
@@ -301,7 +305,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> { | |||
301 | type?: VideoPlaylistType, | 305 | type?: VideoPlaylistType, |
302 | accountId?: number, | 306 | accountId?: number, |
303 | videoChannelId?: number, | 307 | videoChannelId?: number, |
304 | privateAndUnlisted?: boolean, | 308 | listMyPlaylists?: boolean, |
305 | search?: string | 309 | search?: string |
306 | }) { | 310 | }) { |
307 | const query = { | 311 | const query = { |
@@ -319,7 +323,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> { | |||
319 | followerActorId: options.followerActorId, | 323 | followerActorId: options.followerActorId, |
320 | accountId: options.accountId, | 324 | accountId: options.accountId, |
321 | videoChannelId: options.videoChannelId, | 325 | videoChannelId: options.videoChannelId, |
322 | privateAndUnlisted: options.privateAndUnlisted, | 326 | listMyPlaylists: options.listMyPlaylists, |
323 | search: options.search | 327 | search: options.search |
324 | } as AvailableForListOptions | 328 | } as AvailableForListOptions |
325 | ] | 329 | ] |