findById -> findByPk
[oweals/peertube.git] / server / initializers / migrations / 0055-video-uuid.ts
1 import * as Sequelize from 'sequelize'
2 import * as Promise from 'bluebird'
3 import { Migration } from '../../models/migrations'
4
5 function up (utils: {
6   transaction: Sequelize.Transaction,
7   queryInterface: Sequelize.QueryInterface,
8   sequelize: Sequelize.Sequelize
9 }): Promise<void> {
10   const q = utils.queryInterface
11
12   const dataUUID = {
13     type: Sequelize.UUID,
14     defaultValue: Sequelize.UUIDV4,
15     allowNull: true
16   } as Migration.UUID
17
18   return q.addColumn('Videos', 'uuid', dataUUID)
19     .then(() => {
20       const query = 'UPDATE "Videos" SET "uuid" = "id" WHERE "remoteId" IS NULL'
21       return utils.sequelize.query(query)
22     })
23     .then(() => {
24       const query = 'UPDATE "Videos" SET "uuid" = "remoteId" WHERE "remoteId" IS NOT NULL'
25       return utils.sequelize.query(query)
26     })
27     .then(() => {
28       dataUUID.defaultValue = null
29
30       return q.changeColumn('Videos', 'uuid', dataUUID)
31     })
32     .then(() => {
33       return removeForeignKey(utils.sequelize, 'RequestVideoQadus')
34     })
35     .then(() => {
36       return removeForeignKey(utils.sequelize, 'RequestVideoEvents')
37     })
38     .then(() => {
39       return removeForeignKey(utils.sequelize, 'BlacklistedVideos')
40     })
41     .then(() => {
42       return removeForeignKey(utils.sequelize, 'UserVideoRates')
43     })
44     .then(() => {
45       return removeForeignKey(utils.sequelize, 'VideoAbuses')
46     })
47     .then(() => {
48       return removeForeignKey(utils.sequelize, 'VideoTags')
49     })
50     .then(() => {
51       const query = 'ALTER TABLE "Videos" DROP CONSTRAINT "Videos_pkey"'
52       return utils.sequelize.query(query)
53     })
54     .then(() => {
55       const query = 'ALTER TABLE "Videos" ADD COLUMN "id2" SERIAL PRIMARY KEY'
56       return utils.sequelize.query(query)
57     })
58     .then(() => {
59       return q.renameColumn('Videos', 'id', 'oldId')
60     })
61     .then(() => {
62       return q.renameColumn('Videos', 'id2', 'id')
63     })
64     .then(() => {
65       return changeForeignKey(q, utils.sequelize, 'RequestVideoQadus', false)
66     })
67     .then(() => {
68       return changeForeignKey(q, utils.sequelize, 'RequestVideoEvents', false)
69     })
70     .then(() => {
71       return changeForeignKey(q, utils.sequelize, 'BlacklistedVideos', false)
72     })
73     .then(() => {
74       return changeForeignKey(q, utils.sequelize, 'UserVideoRates', false)
75     })
76     .then(() => {
77       return changeForeignKey(q, utils.sequelize, 'VideoAbuses', false)
78     })
79     .then(() => {
80       return changeForeignKey(q, utils.sequelize, 'VideoTags', true)
81     })
82     .then(() => {
83       return q.removeColumn('Videos', 'oldId')
84     })
85     .then(() => {
86       const dataRemote = {
87         type: Sequelize.BOOLEAN,
88         defaultValue: false,
89         allowNull: false
90       }
91       return q.addColumn('Videos', 'remote', dataRemote)
92     })
93     .then(() => {
94       const query = 'UPDATE "Videos" SET "remote" = false WHERE "remoteId" IS NULL'
95       return utils.sequelize.query(query)
96     })
97     .then(() => {
98       const query = 'UPDATE "Videos" SET "remote" = true WHERE "remoteId" IS NOT NULL'
99       return utils.sequelize.query(query)
100     })
101     .then(() => {
102       return q.removeColumn('Videos', 'remoteId')
103     })
104 }
105
106 function down (options) {
107   throw new Error('Not implemented.')
108 }
109
110 function removeForeignKey (sequelize: Sequelize.Sequelize, tableName: string) {
111   const query = 'ALTER TABLE "' + tableName + '" DROP CONSTRAINT "' + tableName + '_videoId_fkey' + '"'
112   return sequelize.query(query)
113 }
114
115 function changeForeignKey (q: Sequelize.QueryInterface, sequelize: Sequelize.Sequelize, tableName: string, allowNull: boolean) {
116   const data = {
117     type: Sequelize.INTEGER,
118     allowNull: true
119   }
120
121   return q.addColumn(tableName, 'videoId2', data)
122     .then(() => {
123       const query = 'UPDATE "' + tableName + '" SET "videoId2" = ' +
124                     '(SELECT "id" FROM "Videos" WHERE "' + tableName + '"."videoId" = "Videos"."oldId")'
125       return sequelize.query(query)
126     })
127     .then(() => {
128       if (allowNull === false) {
129         data.allowNull = false
130
131         return q.changeColumn(tableName, 'videoId2', data)
132       }
133
134       return Promise.resolve()
135     })
136     .then(() => {
137       return q.removeColumn(tableName, 'videoId')
138     })
139     .then(() => {
140       return q.renameColumn(tableName, 'videoId2', 'videoId')
141     })
142     .then(() => {
143       return q.addIndex(tableName, [ 'videoId' ])
144     })
145     .then(() => {
146       const constraintName = tableName + '_videoId_fkey'
147       const query = 'ALTER TABLE "' + tableName + '" ' +
148                     ' ADD CONSTRAINT "' + constraintName + '"' +
149                     ' FOREIGN KEY ("videoId") REFERENCES "Videos" ON DELETE CASCADE'
150
151       return sequelize.query(query)
152     })
153 }
154
155 export {
156   up,
157   down
158 }