aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/initializers/migrations/0135-video-channel-actor.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/initializers/migrations/0135-video-channel-actor.ts')
-rw-r--r--server/initializers/migrations/0135-video-channel-actor.ts268
1 files changed, 268 insertions, 0 deletions
diff --git a/server/initializers/migrations/0135-video-channel-actor.ts b/server/initializers/migrations/0135-video-channel-actor.ts
new file mode 100644
index 000000000..3c5c10ad6
--- /dev/null
+++ b/server/initializers/migrations/0135-video-channel-actor.ts
@@ -0,0 +1,268 @@
1import * as Sequelize from 'sequelize'
2import { DataType } from 'sequelize-typescript'
3import { createPrivateAndPublicKeys } from '../../helpers'
4
5async function up (utils: {
6 transaction: Sequelize.Transaction,
7 queryInterface: Sequelize.QueryInterface,
8 sequelize: Sequelize.Sequelize
9}): Promise<void> {
10 // Create actor table
11 {
12 const queries = [
13 `DROP TYPE IF EXISTS enum_actor_type`,
14 `
15 CREATE TYPE enum_actor_type AS ENUM (
16 'Group',
17 'Person',
18 'Application'
19 )
20 `,
21 `
22 CREATE TABLE actor (
23 id integer NOT NULL,
24 type enum_actor_type NOT NULL,
25 uuid uuid NOT NULL,
26 "preferredUsername" character varying(255) NOT NULL,
27 url character varying(2000) NOT NULL,
28 "publicKey" character varying(5000),
29 "privateKey" character varying(5000),
30 "followersCount" integer NOT NULL,
31 "followingCount" integer NOT NULL,
32 "inboxUrl" character varying(2000) NOT NULL,
33 "outboxUrl" character varying(2000) NOT NULL,
34 "sharedInboxUrl" character varying(2000) NOT NULL,
35 "followersUrl" character varying(2000) NOT NULL,
36 "followingUrl" character varying(2000) NOT NULL,
37 "avatarId" integer,
38 "serverId" integer,
39 "createdAt" timestamp with time zone NOT NULL,
40 "updatedAt" timestamp with time zone NOT NULL
41 );`,
42 `
43 CREATE SEQUENCE actor_id_seq
44 AS integer
45 START WITH 1
46 INCREMENT BY 1
47 NO MINVALUE
48 NO MAXVALUE
49 CACHE 1
50 `,
51 `ALTER SEQUENCE actor_id_seq OWNED BY actor.id`,
52 `ALTER TABLE ONLY actor ALTER COLUMN id SET DEFAULT nextval('actor_id_seq'::regclass)`,
53 `ALTER TABLE ONLY actor ADD CONSTRAINT actor_pkey PRIMARY KEY (id);`,
54 `CREATE UNIQUE INDEX actor_preferred_username_server_id ON actor USING btree ("preferredUsername", "serverId")`,
55 `ALTER TABLE ONLY actor
56 ADD CONSTRAINT "actor_avatarId_fkey" FOREIGN KEY ("avatarId") REFERENCES avatar(id) ON UPDATE CASCADE ON DELETE CASCADE`,
57 `ALTER TABLE ONLY actor
58 ADD CONSTRAINT "actor_serverId_fkey" FOREIGN KEY ("serverId") REFERENCES server(id) ON UPDATE CASCADE ON DELETE CASCADE;`
59 ]
60
61 for (const query of queries) {
62 await utils.sequelize.query(query)
63 }
64 }
65
66 {
67 // tslint:disable:no-trailing-whitespace
68 const query1 =
69 `
70 INSERT INTO "actor"
71 (
72 type, uuid, "preferredUsername", url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
73 "sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
74 )
75 SELECT
76 'Application', uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
77 "sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
78 FROM account
79 WHERE "applicationId" IS NOT NULL
80 `
81 await utils.sequelize.query(query1)
82
83 const query2 =
84 `
85 INSERT INTO "actor"
86 (
87 type, uuid, "preferredUsername", url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
88 "sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
89 )
90 SELECT
91 'Person', uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
92 "sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
93 FROM account
94 WHERE "applicationId" IS NULL
95 `
96 await utils.sequelize.query(query2)
97 }
98
99 {
100 const data = {
101 type: DataType.INTEGER,
102 allowNull: true,
103 references: {
104 model: 'actor',
105 key: 'id'
106 },
107 onDelete: 'CASCADE'
108 }
109 await utils.queryInterface.addColumn('account', 'actorId', data)
110
111 const query1 = `UPDATE account SET "actorId" = (SELECT id FROM actor WHERE actor.url = account.url)`
112 await utils.sequelize.query(query1)
113
114 data.allowNull = false
115 await utils.queryInterface.changeColumn('account', 'actorId', data)
116 }
117
118 {
119 const query = `
120 INSERT INTO actor
121 (
122 type, uuid, "preferredUsername", url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
123 "sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
124 )
125 SELECT
126 'Group', "videoChannel".uuid, "videoChannel".uuid, "videoChannel".url, null, null, 0, 0, "videoChannel".url || '/inbox',
127 "videoChannel".url || '/outbox', "videoChannel".url || '/inbox', "videoChannel".url || '/followers', "videoChannel".url || '/following',
128 null, account."serverId", "videoChannel"."createdAt", "videoChannel"."updatedAt"
129 FROM "videoChannel"
130 INNER JOIN "account" on "videoChannel"."accountId" = "account".id
131 `
132 await utils.sequelize.query(query)
133 }
134
135 {
136 const data = {
137 type: DataType.INTEGER,
138 allowNull: true,
139 references: {
140 model: 'actor',
141 key: 'id'
142 },
143 onDelete: 'CASCADE'
144 }
145 await utils.queryInterface.addColumn('videoChannel', 'actorId', data)
146
147 const query1 = `UPDATE "videoChannel" SET "actorId" = (SELECT id FROM actor WHERE actor.url = "videoChannel".url)`
148 await utils.sequelize.query(query1)
149
150 data.allowNull = false
151 await utils.queryInterface.changeColumn('videoChannel', 'actorId', data)
152 }
153
154 {
155 await utils.queryInterface.renameTable('accountFollow', 'actorFollow')
156 await utils.queryInterface.renameColumn('actorFollow', 'accountId', 'actorId')
157 await utils.queryInterface.renameColumn('actorFollow', 'targetAccountId', 'targetActorId')
158
159 try {
160 await utils.queryInterface.removeConstraint('actorFollow', 'AccountFollows_accountId_fkey')
161 await utils.queryInterface.removeConstraint('actorFollow', 'AccountFollows_targetAccountId_fkey')
162 } catch {
163 await utils.queryInterface.removeConstraint('actorFollow', 'accountFollow_accountId_fkey')
164 await utils.queryInterface.removeConstraint('actorFollow', 'accountFollow_targetAccountId_fkey')
165 }
166
167 {
168 const query1 = `UPDATE "actorFollow"
169 SET "actorId" =
170 (SELECT "account"."actorId" FROM account WHERE "account"."id" = "actorFollow"."actorId")`
171 await utils.sequelize.query(query1)
172
173 const query2 = `UPDATE "actorFollow"
174 SET "targetActorId" =
175 (SELECT "account"."actorId" FROM account WHERE "account"."id" = "actorFollow"."targetActorId")`
176
177 await utils.sequelize.query(query2)
178 }
179
180 {
181 const query1 = `ALTER TABLE ONLY "actorFollow"
182 ADD CONSTRAINT "actorFollow_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES actor(id) ON UPDATE CASCADE ON DELETE CASCADE;`
183 await utils.sequelize.query(query1)
184
185 const query2 = `ALTER TABLE ONLY "actorFollow"
186 ADD CONSTRAINT "actorFollow_targetActorId_fkey" FOREIGN KEY ("targetActorId") REFERENCES actor(id) ON UPDATE CASCADE ON DELETE CASCADE;`
187 await utils.sequelize.query(query2)
188 }
189 }
190
191 {
192 await utils.queryInterface.renameColumn('videoShare', 'accountId', 'actorId')
193
194 try {
195 await utils.queryInterface.removeConstraint('videoShare', 'VideoShares_accountId_fkey')
196 } catch {
197 await utils.queryInterface.removeConstraint('videoShare', 'videoShare_accountId_fkey')
198 }
199
200 const query = `UPDATE "videoShare"
201 SET "actorId" =
202 (SELECT "actorId" FROM account WHERE id = "videoShare"."actorId")`
203 await utils.sequelize.query(query)
204
205 {
206 const query1 = `ALTER TABLE ONLY "videoShare"
207 ADD CONSTRAINT "videoShare_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES actor(id) ON UPDATE CASCADE ON DELETE CASCADE;`
208 await utils.sequelize.query(query1)
209
210 const query2 = `ALTER TABLE ONLY "videoShare"
211 ADD CONSTRAINT "videoShare_videoId_fkey" FOREIGN KEY ("videoId") REFERENCES video(id) ON UPDATE CASCADE ON DELETE CASCADE;`
212 await utils.sequelize.query(query2)
213 }
214 }
215
216 {
217 const columnsToDelete = [
218 'uuid',
219 'url',
220 'publicKey',
221 'privateKey',
222 'followersCount',
223 'followingCount',
224 'inboxUrl',
225 'outboxUrl',
226 'sharedInboxUrl',
227 'followersUrl',
228 'followingUrl',
229 'serverId',
230 'avatarId'
231 ]
232 for (const columnToDelete of columnsToDelete) {
233 await utils.queryInterface.removeColumn('account', columnToDelete)
234 }
235 }
236
237 {
238 const columnsToDelete = [
239 'uuid',
240 'remote',
241 'url'
242 ]
243 for (const columnToDelete of columnsToDelete) {
244 await utils.queryInterface.removeColumn('videoChannel', columnToDelete)
245 }
246 }
247
248 {
249 const query = 'SELECT * FROM "actor" WHERE "serverId" IS NULL AND "publicKey" IS NULL'
250 const [ res ] = await utils.sequelize.query(query)
251
252 for (const actor of res) {
253 const { privateKey, publicKey } = await createPrivateAndPublicKeys()
254
255 const queryUpdate = `UPDATE "actor" SET "publicKey" = '${publicKey}', "privateKey" = '${privateKey}' WHERE id = ${actor.id}`
256 await utils.sequelize.query(queryUpdate)
257 }
258 }
259}
260
261function down (options) {
262 throw new Error('Not implemented.')
263}
264
265export {
266 up,
267 down
268}