diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-15 09:17:19 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-15 10:40:06 +0200 |
commit | eae0365b5c5468e51e9795b0e894815ebda86b4a (patch) | |
tree | 5da54b28c94d43d1715a0c69e35eb1cf3a1a959d /server | |
parent | 51f636ad0f928bb94069c9143e38df0518f6e4a7 (diff) | |
download | PeerTube-eae0365b5c5468e51e9795b0e894815ebda86b4a.tar.gz PeerTube-eae0365b5c5468e51e9795b0e894815ebda86b4a.tar.zst PeerTube-eae0365b5c5468e51e9795b0e894815ebda86b4a.zip |
Fix missing transactions
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/server/follows.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/videos/ownership.ts | 4 | ||||
-rw-r--r-- | server/lib/activitypub/follow.ts | 13 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-delete.ts | 7 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-follow.ts | 7 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-undo.ts | 4 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-transcoding.ts | 50 | ||||
-rw-r--r-- | server/lib/moderation.ts | 2 | ||||
-rw-r--r-- | server/lib/user.ts | 8 | ||||
-rw-r--r-- | server/lib/video-comment.ts | 13 | ||||
-rw-r--r-- | server/models/server/server.ts | 6 | ||||
-rw-r--r-- | server/models/video/video-caption.ts | 10 | ||||
-rw-r--r-- | server/models/video/video-channel.ts | 4 | ||||
-rw-r--r-- | server/models/video/video-comment.ts | 6 |
14 files changed, 66 insertions, 70 deletions
diff --git a/server/controllers/api/server/follows.ts b/server/controllers/api/server/follows.ts index daeef22de..12357a2ca 100644 --- a/server/controllers/api/server/follows.ts +++ b/server/controllers/api/server/follows.ts | |||
@@ -176,7 +176,7 @@ async function removeOrRejectFollower (req: express.Request, res: express.Respon | |||
176 | async function acceptFollower (req: express.Request, res: express.Response) { | 176 | async function acceptFollower (req: express.Request, res: express.Response) { |
177 | const follow = res.locals.follow | 177 | const follow = res.locals.follow |
178 | 178 | ||
179 | await sendAccept(follow) | 179 | sendAccept(follow) |
180 | 180 | ||
181 | follow.state = 'accepted' | 181 | follow.state = 'accepted' |
182 | await follow.save() | 182 | await follow.save() |
diff --git a/server/controllers/api/videos/ownership.ts b/server/controllers/api/videos/ownership.ts index 2d6ca60a8..1bb96e046 100644 --- a/server/controllers/api/videos/ownership.ts +++ b/server/controllers/api/videos/ownership.ts | |||
@@ -105,9 +105,9 @@ function acceptOwnership (req: express.Request, res: express.Response) { | |||
105 | const channel = res.locals.videoChannel | 105 | const channel = res.locals.videoChannel |
106 | 106 | ||
107 | // We need more attributes for federation | 107 | // We need more attributes for federation |
108 | const targetVideo = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoChangeOwnership.Video.id) | 108 | const targetVideo = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoChangeOwnership.Video.id, t) |
109 | 109 | ||
110 | const oldVideoChannel = await VideoChannelModel.loadAndPopulateAccount(targetVideo.channelId) | 110 | const oldVideoChannel = await VideoChannelModel.loadAndPopulateAccount(targetVideo.channelId, t) |
111 | 111 | ||
112 | targetVideo.channelId = channel.id | 112 | targetVideo.channelId = channel.id |
113 | 113 | ||
diff --git a/server/lib/activitypub/follow.ts b/server/lib/activitypub/follow.ts index 351499bd1..c1bd667e0 100644 --- a/server/lib/activitypub/follow.ts +++ b/server/lib/activitypub/follow.ts | |||
@@ -1,12 +1,13 @@ | |||
1 | import { MActorFollowActors } from '../../types/models' | 1 | import { Transaction } from 'sequelize' |
2 | import { getServerActor } from '@server/models/application/application' | ||
3 | import { logger } from '../../helpers/logger' | ||
2 | import { CONFIG } from '../../initializers/config' | 4 | import { CONFIG } from '../../initializers/config' |
3 | import { SERVER_ACTOR_NAME } from '../../initializers/constants' | 5 | import { SERVER_ACTOR_NAME } from '../../initializers/constants' |
4 | import { JobQueue } from '../job-queue' | ||
5 | import { logger } from '../../helpers/logger' | ||
6 | import { ServerModel } from '../../models/server/server' | 6 | import { ServerModel } from '../../models/server/server' |
7 | import { getServerActor } from '@server/models/application/application' | 7 | import { MActorFollowActors } from '../../types/models' |
8 | import { JobQueue } from '../job-queue' | ||
8 | 9 | ||
9 | async function autoFollowBackIfNeeded (actorFollow: MActorFollowActors) { | 10 | async function autoFollowBackIfNeeded (actorFollow: MActorFollowActors, transaction?: Transaction) { |
10 | if (!CONFIG.FOLLOWINGS.INSTANCE.AUTO_FOLLOW_BACK.ENABLED) return | 11 | if (!CONFIG.FOLLOWINGS.INSTANCE.AUTO_FOLLOW_BACK.ENABLED) return |
11 | 12 | ||
12 | const follower = actorFollow.ActorFollower | 13 | const follower = actorFollow.ActorFollower |
@@ -16,7 +17,7 @@ async function autoFollowBackIfNeeded (actorFollow: MActorFollowActors) { | |||
16 | 17 | ||
17 | const me = await getServerActor() | 18 | const me = await getServerActor() |
18 | 19 | ||
19 | const server = await ServerModel.load(follower.serverId) | 20 | const server = await ServerModel.load(follower.serverId, transaction) |
20 | const host = server.host | 21 | const host = server.host |
21 | 22 | ||
22 | const payload = { | 23 | const payload = { |
diff --git a/server/lib/activitypub/process/process-delete.ts b/server/lib/activitypub/process/process-delete.ts index 44f6a87b0..1d2279df5 100644 --- a/server/lib/activitypub/process/process-delete.ts +++ b/server/lib/activitypub/process/process-delete.ts | |||
@@ -16,7 +16,6 @@ import { | |||
16 | MChannelActor, | 16 | MChannelActor, |
17 | MCommentOwnerVideo | 17 | MCommentOwnerVideo |
18 | } from '../../../types/models' | 18 | } from '../../../types/models' |
19 | import { markCommentAsDeleted } from '../../video-comment' | ||
20 | import { forwardVideoRelatedActivity } from '../send/utils' | 19 | import { forwardVideoRelatedActivity } from '../send/utils' |
21 | 20 | ||
22 | async function processDeleteActivity (options: APProcessorOptions<ActivityDelete>) { | 21 | async function processDeleteActivity (options: APProcessorOptions<ActivityDelete>) { |
@@ -139,11 +138,9 @@ function processDeleteVideoComment (byActor: MActorSignature, videoComment: MCom | |||
139 | throw new Error(`Account ${byActor.url} does not own video comment ${videoComment.url} or video ${videoComment.Video.url}`) | 138 | throw new Error(`Account ${byActor.url} does not own video comment ${videoComment.url} or video ${videoComment.Video.url}`) |
140 | } | 139 | } |
141 | 140 | ||
142 | await sequelizeTypescript.transaction(async t => { | 141 | videoComment.markAsDeleted() |
143 | markCommentAsDeleted(videoComment) | ||
144 | 142 | ||
145 | await videoComment.save() | 143 | await videoComment.save({ transaction: t }) |
146 | }) | ||
147 | 144 | ||
148 | if (videoComment.Video.isOwned()) { | 145 | if (videoComment.Video.isOwned()) { |
149 | // Don't resend the activity to the sender | 146 | // Don't resend the activity to the sender |
diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts index 9009c6469..f85238f8e 100644 --- a/server/lib/activitypub/process/process-follow.ts +++ b/server/lib/activitypub/process/process-follow.ts | |||
@@ -43,7 +43,7 @@ async function processFollow (byActor: MActorSignature, activityId: string, targ | |||
43 | if (isFollowingInstance && CONFIG.FOLLOWERS.INSTANCE.ENABLED === false) { | 43 | if (isFollowingInstance && CONFIG.FOLLOWERS.INSTANCE.ENABLED === false) { |
44 | logger.info('Rejecting %s because instance followers are disabled.', targetActor.url) | 44 | logger.info('Rejecting %s because instance followers are disabled.', targetActor.url) |
45 | 45 | ||
46 | await sendReject(activityId, byActor, targetActor) | 46 | sendReject(activityId, byActor, targetActor) |
47 | 47 | ||
48 | return { actorFollow: undefined as MActorFollowActors } | 48 | return { actorFollow: undefined as MActorFollowActors } |
49 | } | 49 | } |
@@ -84,8 +84,9 @@ async function processFollow (byActor: MActorSignature, activityId: string, targ | |||
84 | 84 | ||
85 | // Target sends to actor he accepted the follow request | 85 | // Target sends to actor he accepted the follow request |
86 | if (actorFollow.state === 'accepted') { | 86 | if (actorFollow.state === 'accepted') { |
87 | await sendAccept(actorFollow) | 87 | sendAccept(actorFollow) |
88 | await autoFollowBackIfNeeded(actorFollow) | 88 | |
89 | await autoFollowBackIfNeeded(actorFollow, t) | ||
89 | } | 90 | } |
90 | 91 | ||
91 | return { actorFollow, created, isFollowingInstance, targetActor } | 92 | return { actorFollow, created, isFollowingInstance, targetActor } |
diff --git a/server/lib/activitypub/process/process-undo.ts b/server/lib/activitypub/process/process-undo.ts index fdb8dac24..d4b2a795f 100644 --- a/server/lib/activitypub/process/process-undo.ts +++ b/server/lib/activitypub/process/process-undo.ts | |||
@@ -106,7 +106,7 @@ async function processUndoCacheFile (byActor: MActorSignature, activity: Activit | |||
106 | const { video } = await getOrCreateAPVideo({ videoObject: cacheFileObject.object }) | 106 | const { video } = await getOrCreateAPVideo({ videoObject: cacheFileObject.object }) |
107 | 107 | ||
108 | return sequelizeTypescript.transaction(async t => { | 108 | return sequelizeTypescript.transaction(async t => { |
109 | const cacheFile = await VideoRedundancyModel.loadByUrl(cacheFileObject.id) | 109 | const cacheFile = await VideoRedundancyModel.loadByUrl(cacheFileObject.id, t) |
110 | if (!cacheFile) { | 110 | if (!cacheFile) { |
111 | logger.debug('Cannot undo unknown video cache %s.', cacheFileObject.id) | 111 | logger.debug('Cannot undo unknown video cache %s.', cacheFileObject.id) |
112 | return | 112 | return |
@@ -114,7 +114,7 @@ async function processUndoCacheFile (byActor: MActorSignature, activity: Activit | |||
114 | 114 | ||
115 | if (cacheFile.actorId !== byActor.id) throw new Error('Cannot delete redundancy ' + cacheFile.url + ' of another actor.') | 115 | if (cacheFile.actorId !== byActor.id) throw new Error('Cannot delete redundancy ' + cacheFile.url + ' of another actor.') |
116 | 116 | ||
117 | await cacheFile.destroy() | 117 | await cacheFile.destroy({ transaction: t }) |
118 | 118 | ||
119 | if (video.isOwned()) { | 119 | if (video.isOwned()) { |
120 | // Don't resend the activity to the sender | 120 | // Don't resend the activity to the sender |
diff --git a/server/lib/job-queue/handlers/video-transcoding.ts b/server/lib/job-queue/handlers/video-transcoding.ts index 8d659daa6..8f218ca3a 100644 --- a/server/lib/job-queue/handlers/video-transcoding.ts +++ b/server/lib/job-queue/handlers/video-transcoding.ts | |||
@@ -151,35 +151,31 @@ async function onVideoFileOptimizer ( | |||
151 | // Outside the transaction (IO on disk) | 151 | // Outside the transaction (IO on disk) |
152 | const { videoFileResolution, isPortraitMode } = await videoArg.getMaxQualityResolution() | 152 | const { videoFileResolution, isPortraitMode } = await videoArg.getMaxQualityResolution() |
153 | 153 | ||
154 | const { videoDatabase, videoPublished } = await sequelizeTypescript.transaction(async t => { | 154 | // Maybe the video changed in database, refresh it |
155 | // Maybe the video changed in database, refresh it | 155 | const videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoArg.uuid) |
156 | const videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoArg.uuid, t) | 156 | // Video does not exist anymore |
157 | // Video does not exist anymore | 157 | if (!videoDatabase) return undefined |
158 | if (!videoDatabase) return undefined | 158 | |
159 | 159 | let videoPublished = false | |
160 | let videoPublished = false | 160 | |
161 | 161 | // Generate HLS version of the original file | |
162 | // Generate HLS version of the original file | 162 | const originalFileHLSPayload = Object.assign({}, payload, { |
163 | const originalFileHLSPayload = Object.assign({}, payload, { | 163 | isPortraitMode, |
164 | isPortraitMode, | 164 | resolution: videoDatabase.getMaxQualityFile().resolution, |
165 | resolution: videoDatabase.getMaxQualityFile().resolution, | 165 | // If we quick transcoded original file, force transcoding for HLS to avoid some weird playback issues |
166 | // If we quick transcoded original file, force transcoding for HLS to avoid some weird playback issues | 166 | copyCodecs: transcodeType !== 'quick-transcode', |
167 | copyCodecs: transcodeType !== 'quick-transcode', | 167 | isMaxQuality: true |
168 | isMaxQuality: true | 168 | }) |
169 | }) | 169 | const hasHls = await createHlsJobIfEnabled(user, originalFileHLSPayload) |
170 | const hasHls = await createHlsJobIfEnabled(user, originalFileHLSPayload) | ||
171 | |||
172 | const hasNewResolutions = await createLowerResolutionsJobs(videoDatabase, user, videoFileResolution, isPortraitMode, 'webtorrent') | ||
173 | |||
174 | if (!hasHls && !hasNewResolutions) { | ||
175 | // No transcoding to do, it's now published | ||
176 | videoPublished = await videoDatabase.publishIfNeededAndSave(t) | ||
177 | } | ||
178 | 170 | ||
179 | await federateVideoIfNeeded(videoDatabase, payload.isNewVideo, t) | 171 | const hasNewResolutions = await createLowerResolutionsJobs(videoDatabase, user, videoFileResolution, isPortraitMode, 'webtorrent') |
180 | 172 | ||
181 | return { videoDatabase, videoPublished } | 173 | if (!hasHls && !hasNewResolutions) { |
182 | }) | 174 | // No transcoding to do, it's now published |
175 | videoPublished = await videoDatabase.publishIfNeededAndSave(undefined) | ||
176 | } | ||
177 | |||
178 | await federateVideoIfNeeded(videoDatabase, payload.isNewVideo) | ||
183 | 179 | ||
184 | if (payload.isNewVideo) Notifier.Instance.notifyOnNewVideoIfNeeded(videoDatabase) | 180 | if (payload.isNewVideo) Notifier.Instance.notifyOnNewVideoIfNeeded(videoDatabase) |
185 | if (videoPublished) Notifier.Instance.notifyOnVideoPublishedAfterTranscoding(videoDatabase) | 181 | if (videoPublished) Notifier.Instance.notifyOnVideoPublishedAfterTranscoding(videoDatabase) |
diff --git a/server/lib/moderation.ts b/server/lib/moderation.ts index 0cefe1648..14e00518e 100644 --- a/server/lib/moderation.ts +++ b/server/lib/moderation.ts | |||
@@ -221,7 +221,7 @@ async function createAbuse (options: { | |||
221 | const { isOwned } = await associateFun(abuseInstance) | 221 | const { isOwned } = await associateFun(abuseInstance) |
222 | 222 | ||
223 | if (isOwned === false) { | 223 | if (isOwned === false) { |
224 | await sendAbuse(reporterAccount.Actor, abuseInstance, abuseInstance.FlaggedAccount, transaction) | 224 | sendAbuse(reporterAccount.Actor, abuseInstance, abuseInstance.FlaggedAccount, transaction) |
225 | } | 225 | } |
226 | 226 | ||
227 | const abuseJSON = abuseInstance.toFormattedAdminJSON() | 227 | const abuseJSON = abuseInstance.toFormattedAdminJSON() |
diff --git a/server/lib/user.ts b/server/lib/user.ts index a2163abb1..91a682a7e 100644 --- a/server/lib/user.ts +++ b/server/lib/user.ts | |||
@@ -44,11 +44,11 @@ async function createUserAccountAndChannelAndPlaylist (parameters: { | |||
44 | displayName: userDisplayName, | 44 | displayName: userDisplayName, |
45 | userId: userCreated.id, | 45 | userId: userCreated.id, |
46 | applicationId: null, | 46 | applicationId: null, |
47 | t: t | 47 | t |
48 | }) | 48 | }) |
49 | userCreated.Account = accountCreated | 49 | userCreated.Account = accountCreated |
50 | 50 | ||
51 | const channelAttributes = await buildChannelAttributes(userCreated, channelNames) | 51 | const channelAttributes = await buildChannelAttributes(userCreated, t, channelNames) |
52 | const videoChannel = await createLocalVideoChannel(channelAttributes, accountCreated, t) | 52 | const videoChannel = await createLocalVideoChannel(channelAttributes, accountCreated, t) |
53 | 53 | ||
54 | const videoPlaylist = await createWatchLaterPlaylist(accountCreated, t) | 54 | const videoPlaylist = await createWatchLaterPlaylist(accountCreated, t) |
@@ -203,13 +203,13 @@ function createDefaultUserNotificationSettings (user: MUserId, t: Transaction | | |||
203 | return UserNotificationSettingModel.create(values, { transaction: t }) | 203 | return UserNotificationSettingModel.create(values, { transaction: t }) |
204 | } | 204 | } |
205 | 205 | ||
206 | async function buildChannelAttributes (user: MUser, channelNames?: ChannelNames) { | 206 | async function buildChannelAttributes (user: MUser, transaction?: Transaction, channelNames?: ChannelNames) { |
207 | if (channelNames) return channelNames | 207 | if (channelNames) return channelNames |
208 | 208 | ||
209 | let channelName = user.username + '_channel' | 209 | let channelName = user.username + '_channel' |
210 | 210 | ||
211 | // Conflict, generate uuid instead | 211 | // Conflict, generate uuid instead |
212 | const actor = await ActorModel.loadLocalByName(channelName) | 212 | const actor = await ActorModel.loadLocalByName(channelName, transaction) |
213 | if (actor) channelName = uuidv4() | 213 | if (actor) channelName = uuidv4() |
214 | 214 | ||
215 | const videoChannelDisplayName = `Main ${user.username} channel` | 215 | const videoChannelDisplayName = `Main ${user.username} channel` |
diff --git a/server/lib/video-comment.ts b/server/lib/video-comment.ts index 51a9c747e..c76570a5d 100644 --- a/server/lib/video-comment.ts +++ b/server/lib/video-comment.ts | |||
@@ -18,9 +18,9 @@ async function removeComment (videoCommentInstance: MCommentOwnerVideo) { | |||
18 | await sendDeleteVideoComment(videoCommentInstance, t) | 18 | await sendDeleteVideoComment(videoCommentInstance, t) |
19 | } | 19 | } |
20 | 20 | ||
21 | markCommentAsDeleted(videoCommentInstance) | 21 | videoCommentInstance.markAsDeleted() |
22 | 22 | ||
23 | await videoCommentInstance.save() | 23 | await videoCommentInstance.save({ transaction: t }) |
24 | }) | 24 | }) |
25 | 25 | ||
26 | logger.info('Video comment %d deleted.', videoCommentInstance.id) | 26 | logger.info('Video comment %d deleted.', videoCommentInstance.id) |
@@ -95,17 +95,10 @@ function buildFormattedCommentTree (resultList: ResultList<VideoCommentModel>): | |||
95 | return thread | 95 | return thread |
96 | } | 96 | } |
97 | 97 | ||
98 | function markCommentAsDeleted (comment: MComment): void { | ||
99 | comment.text = '' | ||
100 | comment.deletedAt = new Date() | ||
101 | comment.accountId = null | ||
102 | } | ||
103 | |||
104 | // --------------------------------------------------------------------------- | 98 | // --------------------------------------------------------------------------- |
105 | 99 | ||
106 | export { | 100 | export { |
107 | removeComment, | 101 | removeComment, |
108 | createVideoComment, | 102 | createVideoComment, |
109 | buildFormattedCommentTree, | 103 | buildFormattedCommentTree |
110 | markCommentAsDeleted | ||
111 | } | 104 | } |
diff --git a/server/models/server/server.ts b/server/models/server/server.ts index 25d9924fb..0d3c092e0 100644 --- a/server/models/server/server.ts +++ b/server/models/server/server.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import { Transaction } from 'sequelize' | ||
1 | import { AllowNull, Column, CreatedAt, Default, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' | 2 | import { AllowNull, Column, CreatedAt, Default, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' |
2 | import { MServer, MServerFormattable } from '@server/types/models/server' | 3 | import { MServer, MServerFormattable } from '@server/types/models/server' |
3 | import { AttributesOnly } from '@shared/core-utils' | 4 | import { AttributesOnly } from '@shared/core-utils' |
@@ -51,11 +52,12 @@ export class ServerModel extends Model<Partial<AttributesOnly<ServerModel>>> { | |||
51 | }) | 52 | }) |
52 | BlockedByAccounts: ServerBlocklistModel[] | 53 | BlockedByAccounts: ServerBlocklistModel[] |
53 | 54 | ||
54 | static load (id: number): Promise<MServer> { | 55 | static load (id: number, transaction?: Transaction): Promise<MServer> { |
55 | const query = { | 56 | const query = { |
56 | where: { | 57 | where: { |
57 | id | 58 | id |
58 | } | 59 | }, |
60 | transaction | ||
59 | } | 61 | } |
60 | 62 | ||
61 | return ServerModel.findOne(query) | 63 | return ServerModel.findOne(query) |
diff --git a/server/models/video/video-caption.ts b/server/models/video/video-caption.ts index bbda0f3ee..5ec944b9e 100644 --- a/server/models/video/video-caption.ts +++ b/server/models/video/video-caption.ts | |||
@@ -91,9 +91,9 @@ export class VideoCaptionModel extends Model<Partial<AttributesOnly<VideoCaption | |||
91 | Video: VideoModel | 91 | Video: VideoModel |
92 | 92 | ||
93 | @BeforeDestroy | 93 | @BeforeDestroy |
94 | static async removeFiles (instance: VideoCaptionModel) { | 94 | static async removeFiles (instance: VideoCaptionModel, options) { |
95 | if (!instance.Video) { | 95 | if (!instance.Video) { |
96 | instance.Video = await instance.$get('Video') | 96 | instance.Video = await instance.$get('Video', { transaction: options.transaction }) |
97 | } | 97 | } |
98 | 98 | ||
99 | if (instance.isOwned()) { | 99 | if (instance.isOwned()) { |
@@ -113,8 +113,7 @@ export class VideoCaptionModel extends Model<Partial<AttributesOnly<VideoCaption | |||
113 | const videoInclude = { | 113 | const videoInclude = { |
114 | model: VideoModel.unscoped(), | 114 | model: VideoModel.unscoped(), |
115 | attributes: [ 'id', 'remote', 'uuid' ], | 115 | attributes: [ 'id', 'remote', 'uuid' ], |
116 | where: buildWhereIdOrUUID(videoId), | 116 | where: buildWhereIdOrUUID(videoId) |
117 | transaction | ||
118 | } | 117 | } |
119 | 118 | ||
120 | const query = { | 119 | const query = { |
@@ -123,7 +122,8 @@ export class VideoCaptionModel extends Model<Partial<AttributesOnly<VideoCaption | |||
123 | }, | 122 | }, |
124 | include: [ | 123 | include: [ |
125 | videoInclude | 124 | videoInclude |
126 | ] | 125 | ], |
126 | transaction | ||
127 | } | 127 | } |
128 | 128 | ||
129 | return VideoCaptionModel.findOne(query) | 129 | return VideoCaptionModel.findOne(query) |
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index 8c4357009..33749ea70 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts | |||
@@ -522,10 +522,10 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"` | |||
522 | }) | 522 | }) |
523 | } | 523 | } |
524 | 524 | ||
525 | static loadAndPopulateAccount (id: number): Promise<MChannelBannerAccountDefault> { | 525 | static loadAndPopulateAccount (id: number, transaction?: Transaction): Promise<MChannelBannerAccountDefault> { |
526 | return VideoChannelModel.unscoped() | 526 | return VideoChannelModel.unscoped() |
527 | .scope([ ScopeNames.WITH_ACTOR_BANNER, ScopeNames.WITH_ACCOUNT ]) | 527 | .scope([ ScopeNames.WITH_ACTOR_BANNER, ScopeNames.WITH_ACCOUNT ]) |
528 | .findByPk(id) | 528 | .findByPk(id, { transaction }) |
529 | } | 529 | } |
530 | 530 | ||
531 | static loadByUrlAndPopulateAccount (url: string): Promise<MChannelBannerAccountDefault> { | 531 | static loadByUrlAndPopulateAccount (url: string): Promise<MChannelBannerAccountDefault> { |
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index e1faf2b9a..e933989ae 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts | |||
@@ -739,6 +739,12 @@ export class VideoCommentModel extends Model<Partial<AttributesOnly<VideoComment | |||
739 | return this.Account.isOwned() | 739 | return this.Account.isOwned() |
740 | } | 740 | } |
741 | 741 | ||
742 | markAsDeleted () { | ||
743 | this.text = '' | ||
744 | this.deletedAt = new Date() | ||
745 | this.accountId = null | ||
746 | } | ||
747 | |||
742 | isDeleted () { | 748 | isDeleted () { |
743 | return this.deletedAt !== null | 749 | return this.deletedAt !== null |
744 | } | 750 | } |