mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
fix: Add missing indices on sqlite (#6673)
* fix: enforce tag name uniqueness on sqlite * rename migration and add other missing indices * add tags tests
This commit is contained in:
parent
76a765a151
commit
b1838f7fab
|
@ -0,0 +1,40 @@
|
|||
import type { IrreversibleMigration, MigrationContext } from '@db/types';
|
||||
|
||||
export class FixMissingIndicesFromStringIdMigration1690000000020 implements IrreversibleMigration {
|
||||
async up({ queryRunner, tablePrefix }: MigrationContext): Promise<void> {
|
||||
const toMerge = (await queryRunner.query(
|
||||
`SELECT id, name, COUNT(*) c FROM ${tablePrefix}tag_entity GROUP BY name HAVING c > 1`,
|
||||
)) as Array<{ id: string; name: string }>;
|
||||
|
||||
for (const m of toMerge) {
|
||||
const tags = (await queryRunner.query(
|
||||
`SELECT id FROM ${tablePrefix}tag_entity WHERE name = ?`,
|
||||
[m.name],
|
||||
)) as Array<{ id: string }>;
|
||||
for (const t of tags) {
|
||||
if (t.id === m.id) {
|
||||
continue;
|
||||
}
|
||||
await queryRunner.query(
|
||||
`UPDATE ${tablePrefix}workflows_tags SET tagId = ? WHERE tagId = ?`,
|
||||
[m.id, t.id],
|
||||
);
|
||||
await queryRunner.query(`DELETE FROM ${tablePrefix}tag_entity WHERE id = ?`, [t.id]);
|
||||
}
|
||||
}
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE UNIQUE INDEX "IDX_${tablePrefix}8f949d7a3a984759044054e89b" ON "${tablePrefix}tag_entity" ("name") `,
|
||||
);
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX 'IDX_${tablePrefix}b94b45ce2c73ce46c54f20b5f9' ON '${tablePrefix}execution_entity' ('waitTill', 'id');`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX 'IDX_${tablePrefix}81fc04c8a17de15835713505e4' ON '${tablePrefix}execution_entity' ('workflowId', 'id');`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE INDEX 'IDX_${tablePrefix}8b6f3f9ae234f137d707b98f3bf43584' ON '${tablePrefix}execution_entity' ('status', 'workflowId');`,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -38,6 +38,7 @@ import { AddUserActivatedProperty1681134145996 } from './1681134145996-AddUserAc
|
|||
import { MigrateIntegerKeysToString1690000000002 } from './1690000000002-MigrateIntegerKeysToString';
|
||||
import { SeparateExecutionData1690000000010 } from './1690000000010-SeparateExecutionData';
|
||||
import { RemoveSkipOwnerSetup1681134145997 } from './1681134145997-RemoveSkipOwnerSetup';
|
||||
import { FixMissingIndicesFromStringIdMigration1690000000020 } from './1690000000020-FixMissingIndicesFromStringIdMigration';
|
||||
|
||||
const sqliteMigrations: Migration[] = [
|
||||
InitialMigration1588102412422,
|
||||
|
@ -79,6 +80,7 @@ const sqliteMigrations: Migration[] = [
|
|||
MigrateIntegerKeysToString1690000000002,
|
||||
SeparateExecutionData1690000000010,
|
||||
RemoveSkipOwnerSetup1681134145997,
|
||||
FixMissingIndicesFromStringIdMigration1690000000020,
|
||||
];
|
||||
|
||||
export { sqliteMigrations };
|
||||
|
|
|
@ -24,7 +24,8 @@ export type EndpointGroup =
|
|||
| 'sourceControl'
|
||||
| 'eventBus'
|
||||
| 'license'
|
||||
| 'variables';
|
||||
| 'variables'
|
||||
| 'tags';
|
||||
|
||||
export interface SetupProps {
|
||||
applyAuth?: boolean;
|
||||
|
|
|
@ -28,6 +28,7 @@ import {
|
|||
NodesController,
|
||||
OwnerController,
|
||||
PasswordResetController,
|
||||
TagsController,
|
||||
UsersController,
|
||||
} from '@/controllers';
|
||||
import { setupAuthMiddlewares } from '@/middlewares';
|
||||
|
@ -261,6 +262,14 @@ export const setupTestServer = ({
|
|||
logger,
|
||||
}),
|
||||
);
|
||||
break;
|
||||
case 'tags':
|
||||
registerController(
|
||||
app,
|
||||
config,
|
||||
new TagsController({ config, externalHooks, repositories }),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
38
packages/cli/test/integration/tags.api.test.ts
Normal file
38
packages/cli/test/integration/tags.api.test.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
import * as Db from '@/Db';
|
||||
import * as utils from './shared/utils/';
|
||||
import * as testDb from './shared/testDb';
|
||||
import type { SuperAgentTest } from 'supertest';
|
||||
|
||||
let authOwnerAgent: SuperAgentTest;
|
||||
const testServer = utils.setupTestServer({ endpointGroups: ['tags'] });
|
||||
|
||||
beforeAll(async () => {
|
||||
const globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
const ownerShell = await testDb.createUserShell(globalOwnerRole);
|
||||
authOwnerAgent = testServer.authAgentFor(ownerShell);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Tag']);
|
||||
});
|
||||
|
||||
describe('POST /tags', () => {
|
||||
test('should create tag', async () => {
|
||||
const resp = await authOwnerAgent.post('/tags').send({ name: 'test' });
|
||||
expect(resp.statusCode).toBe(200);
|
||||
|
||||
const dbTag = await Db.collections.Tag.findBy({ name: 'test' });
|
||||
expect(dbTag.length === 1);
|
||||
});
|
||||
|
||||
test('should not create duplicate tag', async () => {
|
||||
const newTag = Db.collections.Tag.create({ name: 'test' });
|
||||
await Db.collections.Tag.save(newTag);
|
||||
|
||||
const resp = await authOwnerAgent.post('/tags').send({ name: 'test' });
|
||||
expect(resp.status).toBe(500);
|
||||
|
||||
const dbTag = await Db.collections.Tag.findBy({ name: 'test' });
|
||||
expect(dbTag.length).toBe(1);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue