ニジカ投稿局 https://tv.nizika.tv
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

128 lines
3.1 KiB

  1. import { forceNumber } from '@peertube/peertube-core-utils'
  2. import { Op, QueryTypes, Transaction } from 'sequelize'
  3. import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, IsInt, Table, Unique, UpdatedAt } from 'sequelize-typescript'
  4. import { SequelizeModel } from '../shared/sequelize-type.js'
  5. import { VideoModel } from './video.js'
  6. export type VideoJobInfoColumnType = 'pendingMove' | 'pendingTranscode' | 'pendingTranscription'
  7. @Table({
  8. tableName: 'videoJobInfo',
  9. indexes: [
  10. {
  11. fields: [ 'videoId' ],
  12. where: {
  13. videoId: {
  14. [Op.ne]: null
  15. }
  16. }
  17. }
  18. ]
  19. })
  20. export class VideoJobInfoModel extends SequelizeModel<VideoJobInfoModel> {
  21. @CreatedAt
  22. createdAt: Date
  23. @UpdatedAt
  24. updatedAt: Date
  25. @AllowNull(false)
  26. @Default(0)
  27. @IsInt
  28. @Column
  29. pendingMove: number
  30. @AllowNull(false)
  31. @Default(0)
  32. @IsInt
  33. @Column
  34. pendingTranscode: number
  35. @AllowNull(false)
  36. @Default(0)
  37. @IsInt
  38. @Column
  39. pendingTranscription: number
  40. @ForeignKey(() => VideoModel)
  41. @Unique
  42. @Column
  43. videoId: number
  44. @BelongsTo(() => VideoModel, {
  45. foreignKey: {
  46. allowNull: false
  47. },
  48. onDelete: 'cascade'
  49. })
  50. Video: Awaited<VideoModel>
  51. static load (videoId: number, transaction?: Transaction) {
  52. const where = {
  53. videoId
  54. }
  55. return VideoJobInfoModel.findOne({ where, transaction })
  56. }
  57. static async increaseOrCreate (videoUUID: string, column: VideoJobInfoColumnType, amountArg = 1): Promise<number> {
  58. const options = { type: QueryTypes.SELECT as QueryTypes.SELECT, bind: { videoUUID } }
  59. const amount = forceNumber(amountArg)
  60. const [ result ] = await VideoJobInfoModel.sequelize.query<{ pendingMove: number }>(`
  61. INSERT INTO "videoJobInfo" ("videoId", "${column}", "createdAt", "updatedAt")
  62. SELECT
  63. "video"."id" AS "videoId", ${amount}, NOW(), NOW()
  64. FROM
  65. "video"
  66. WHERE
  67. "video"."uuid" = $videoUUID
  68. ON CONFLICT ("videoId") DO UPDATE
  69. SET
  70. "${column}" = "videoJobInfo"."${column}" + ${amount},
  71. "updatedAt" = NOW()
  72. RETURNING
  73. "${column}"
  74. `, options)
  75. return result[column]
  76. }
  77. static async decrease (videoUUID: string, column: VideoJobInfoColumnType): Promise<number> {
  78. const options = { type: QueryTypes.SELECT as QueryTypes.SELECT, bind: { videoUUID } }
  79. const result = await VideoJobInfoModel.sequelize.query(`
  80. UPDATE
  81. "videoJobInfo"
  82. SET
  83. "${column}" = "videoJobInfo"."${column}" - 1,
  84. "updatedAt" = NOW()
  85. FROM "video"
  86. WHERE
  87. "video"."id" = "videoJobInfo"."videoId" AND "video"."uuid" = $videoUUID
  88. RETURNING
  89. "${column}";
  90. `, options)
  91. if (result.length === 0) return undefined
  92. return result[0][column]
  93. }
  94. static async abortAllTasks (videoUUID: string, column: VideoJobInfoColumnType): Promise<void> {
  95. const options = { type: QueryTypes.UPDATE as QueryTypes.UPDATE, bind: { videoUUID } }
  96. await VideoJobInfoModel.sequelize.query(`
  97. UPDATE
  98. "videoJobInfo"
  99. SET
  100. "${column}" = 0,
  101. "updatedAt" = NOW()
  102. FROM "video"
  103. WHERE
  104. "video"."id" = "videoJobInfo"."videoId" AND "video"."uuid" = $videoUUID
  105. `, options)
  106. }
  107. }