mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 04:47:29 -08:00
fix(core): Add down
method to AddApiKeysTable1724951148974
migration (no-changelog) (#11118)
This commit is contained in:
parent
2161ff1217
commit
1ca14946d9
|
@ -1,8 +1,8 @@
|
||||||
import type { ApiKey } from '@/databases/entities/api-key';
|
import type { ApiKey } from '@/databases/entities/api-key';
|
||||||
import type { MigrationContext } from '@/databases/types';
|
import type { MigrationContext, ReversibleMigration } from '@/databases/types';
|
||||||
import { generateNanoId } from '@/databases/utils/generators';
|
import { generateNanoId } from '@/databases/utils/generators';
|
||||||
|
|
||||||
export class AddApiKeysTable1724951148974 {
|
export class AddApiKeysTable1724951148974 implements ReversibleMigration {
|
||||||
async up({
|
async up({
|
||||||
queryRunner,
|
queryRunner,
|
||||||
escape,
|
escape,
|
||||||
|
@ -55,4 +55,55 @@ export class AddApiKeysTable1724951148974 {
|
||||||
// Drop apiKey column on user's table
|
// Drop apiKey column on user's table
|
||||||
await queryRunner.query(`ALTER TABLE ${userTable} DROP COLUMN ${apiKeyColumn};`);
|
await queryRunner.query(`ALTER TABLE ${userTable} DROP COLUMN ${apiKeyColumn};`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async down({
|
||||||
|
queryRunner,
|
||||||
|
runQuery,
|
||||||
|
schemaBuilder: { dropTable, addColumns, createIndex, column },
|
||||||
|
escape,
|
||||||
|
isMysql,
|
||||||
|
}: MigrationContext) {
|
||||||
|
const userTable = escape.tableName('user');
|
||||||
|
const userApiKeysTable = escape.tableName('user_api_keys');
|
||||||
|
const apiKeyColumn = escape.columnName('apiKey');
|
||||||
|
const userIdColumn = escape.columnName('userId');
|
||||||
|
const idColumn = escape.columnName('id');
|
||||||
|
const createdAtColumn = escape.columnName('createdAt');
|
||||||
|
|
||||||
|
await addColumns('user', [column('apiKey').varchar()]);
|
||||||
|
|
||||||
|
await createIndex('user', ['apiKey'], true);
|
||||||
|
|
||||||
|
const queryToGetUsersApiKeys = isMysql
|
||||||
|
? `
|
||||||
|
SELECT ${userIdColumn},
|
||||||
|
${apiKeyColumn},
|
||||||
|
${createdAtColumn}
|
||||||
|
FROM ${userApiKeysTable} u
|
||||||
|
WHERE ${createdAtColumn} = (SELECT Min(${createdAtColumn})
|
||||||
|
FROM ${userApiKeysTable}
|
||||||
|
WHERE ${userIdColumn} = u.${userIdColumn});`
|
||||||
|
: `
|
||||||
|
SELECT DISTINCT ON
|
||||||
|
(${userIdColumn}) ${userIdColumn},
|
||||||
|
${apiKeyColumn}, ${createdAtColumn}
|
||||||
|
FROM ${userApiKeysTable}
|
||||||
|
ORDER BY ${userIdColumn}, ${createdAtColumn} ASC;`;
|
||||||
|
|
||||||
|
const oldestApiKeysPerUser = (await queryRunner.query(queryToGetUsersApiKeys)) as Array<
|
||||||
|
Partial<ApiKey>
|
||||||
|
>;
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
oldestApiKeysPerUser.map(
|
||||||
|
async (user: { userId: string; apiKey: string }) =>
|
||||||
|
await runQuery(
|
||||||
|
`UPDATE ${userTable} SET ${apiKeyColumn} = :apiKey WHERE ${idColumn} = :userId`,
|
||||||
|
user,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await dropTable('user_api_keys');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import type { ApiKey } from '@/databases/entities/api-key';
|
import type { ApiKey } from '@/databases/entities/api-key';
|
||||||
import type { MigrationContext } from '@/databases/types';
|
import type { MigrationContext, ReversibleMigration } from '@/databases/types';
|
||||||
import { generateNanoId } from '@/databases/utils/generators';
|
import { generateNanoId } from '@/databases/utils/generators';
|
||||||
|
|
||||||
export class AddApiKeysTable1724951148974 {
|
export class AddApiKeysTable1724951148974 implements ReversibleMigration {
|
||||||
|
transaction = false as const;
|
||||||
|
|
||||||
async up({ queryRunner, tablePrefix, runQuery }: MigrationContext) {
|
async up({ queryRunner, tablePrefix, runQuery }: MigrationContext) {
|
||||||
const tableName = `${tablePrefix}user_api_keys`;
|
const tableName = `${tablePrefix}user_api_keys`;
|
||||||
|
|
||||||
|
@ -74,4 +76,52 @@ export class AddApiKeysTable1724951148974 {
|
||||||
// Rename the temporary table to users
|
// Rename the temporary table to users
|
||||||
await queryRunner.query('ALTER TABLE users_new RENAME TO user;');
|
await queryRunner.query('ALTER TABLE users_new RENAME TO user;');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async down({
|
||||||
|
queryRunner,
|
||||||
|
runQuery,
|
||||||
|
tablePrefix,
|
||||||
|
schemaBuilder: { dropTable, createIndex },
|
||||||
|
escape,
|
||||||
|
}: MigrationContext) {
|
||||||
|
const userApiKeysTable = escape.tableName('user_api_keys');
|
||||||
|
const apiKeyColumn = escape.columnName('apiKey');
|
||||||
|
const userIdColumn = escape.columnName('userId');
|
||||||
|
const idColumn = escape.columnName('id');
|
||||||
|
const createdAtColumn = escape.columnName('createdAt');
|
||||||
|
|
||||||
|
const queryToGetUsersApiKeys = `
|
||||||
|
SELECT
|
||||||
|
${userIdColumn},
|
||||||
|
${apiKeyColumn},
|
||||||
|
${createdAtColumn}
|
||||||
|
FROM
|
||||||
|
${userApiKeysTable}
|
||||||
|
WHERE
|
||||||
|
${createdAtColumn} IN(
|
||||||
|
SELECT
|
||||||
|
MIN(${createdAtColumn})
|
||||||
|
FROM ${userApiKeysTable}
|
||||||
|
GROUP BY ${userIdColumn});`;
|
||||||
|
|
||||||
|
const oldestApiKeysPerUser = (await queryRunner.query(queryToGetUsersApiKeys)) as Array<
|
||||||
|
Partial<ApiKey>
|
||||||
|
>;
|
||||||
|
|
||||||
|
await queryRunner.query(`ALTER TABLE ${tablePrefix}user ADD COLUMN "apiKey" varchar;`);
|
||||||
|
|
||||||
|
await createIndex('user', ['apiKey'], true);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
oldestApiKeysPerUser.map(
|
||||||
|
async (user: { userId: string; apiKey: string }) =>
|
||||||
|
await runQuery(
|
||||||
|
`UPDATE ${tablePrefix}user SET ${apiKeyColumn} = :apiKey WHERE ${idColumn} = :userId`,
|
||||||
|
user,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await dropTable('user_api_keys');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue