mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
chore(core): Rename Data Store DB entries to Data Table (no-changelog) (#18670)
This commit is contained in:
@@ -73,8 +73,8 @@ type EntityName =
|
|||||||
| 'InsightsRaw'
|
| 'InsightsRaw'
|
||||||
| 'InsightsByPeriod'
|
| 'InsightsByPeriod'
|
||||||
| 'InsightsMetadata'
|
| 'InsightsMetadata'
|
||||||
| 'DataStore'
|
| 'DataTable'
|
||||||
| 'DataStoreColumn';
|
| 'DataTableColumn';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truncate specific DB tables in a test DB.
|
* Truncate specific DB tables in a test DB.
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import type { MigrationContext, ReversibleMigration } from '../migration-types';
|
||||||
|
|
||||||
|
const TABLE_TABLE_NAME_BEFORE = 'data_store';
|
||||||
|
const COLUMN_TABLE_NAME_BEFORE = 'data_store_column';
|
||||||
|
|
||||||
|
const TABLE_TABLE_NAME_AFTER = 'data_table';
|
||||||
|
const COLUMN_TABLE_NAME_AFTER = 'data_table_column';
|
||||||
|
|
||||||
|
export class ReplaceDataStoreTablesWithDataTables1754475614602 implements ReversibleMigration {
|
||||||
|
async up({ schemaBuilder: { createTable, column, dropTable } }: MigrationContext) {
|
||||||
|
await dropTable(COLUMN_TABLE_NAME_BEFORE);
|
||||||
|
await dropTable(TABLE_TABLE_NAME_BEFORE);
|
||||||
|
|
||||||
|
await createTable(TABLE_TABLE_NAME_AFTER)
|
||||||
|
.withColumns(
|
||||||
|
column('id').varchar(36).primary,
|
||||||
|
column('name').varchar(128).notNull,
|
||||||
|
column('projectId').varchar(36).notNull,
|
||||||
|
)
|
||||||
|
.withForeignKey('projectId', {
|
||||||
|
tableName: 'project',
|
||||||
|
columnName: 'id',
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
.withUniqueConstraintOn(['projectId', 'name']).withTimestamps;
|
||||||
|
|
||||||
|
await createTable(COLUMN_TABLE_NAME_AFTER)
|
||||||
|
.withColumns(
|
||||||
|
column('id').varchar(36).primary.notNull,
|
||||||
|
column('name').varchar(128).notNull,
|
||||||
|
column('type')
|
||||||
|
.varchar(32)
|
||||||
|
.notNull.comment(
|
||||||
|
'Expected: string, number, boolean, or date (not enforced as a constraint)',
|
||||||
|
),
|
||||||
|
column('index').int.notNull.comment('Column order, starting from 0 (0 = first column)'),
|
||||||
|
column('dataTableId').varchar(36).notNull,
|
||||||
|
)
|
||||||
|
.withForeignKey('dataTableId', {
|
||||||
|
tableName: TABLE_TABLE_NAME_AFTER,
|
||||||
|
columnName: 'id',
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
.withUniqueConstraintOn(['dataTableId', 'name']).withTimestamps;
|
||||||
|
}
|
||||||
|
|
||||||
|
async down({ schemaBuilder: { createTable, column, dropTable } }: MigrationContext) {
|
||||||
|
await dropTable(COLUMN_TABLE_NAME_AFTER);
|
||||||
|
await dropTable(TABLE_TABLE_NAME_AFTER);
|
||||||
|
|
||||||
|
await createTable(TABLE_TABLE_NAME_BEFORE)
|
||||||
|
.withColumns(
|
||||||
|
column('id').varchar(36).primary,
|
||||||
|
column('name').varchar(128).notNull,
|
||||||
|
column('projectId').varchar(36).notNull,
|
||||||
|
column('sizeBytes').int.default(0).notNull,
|
||||||
|
)
|
||||||
|
.withForeignKey('projectId', {
|
||||||
|
tableName: 'project',
|
||||||
|
columnName: 'id',
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
.withUniqueConstraintOn(['projectId', 'name']).withTimestamps;
|
||||||
|
|
||||||
|
await createTable(COLUMN_TABLE_NAME_BEFORE)
|
||||||
|
.withColumns(
|
||||||
|
column('id').varchar(36).primary.notNull,
|
||||||
|
column('name').varchar(128).notNull,
|
||||||
|
column('type')
|
||||||
|
.varchar(32)
|
||||||
|
.notNull.comment(
|
||||||
|
'Expected: string, number, boolean, or date (not enforced as a constraint)',
|
||||||
|
),
|
||||||
|
column('index').int.notNull.comment('Column order, starting from 0 (0 = first column)'),
|
||||||
|
column('dataStoreId').varchar(36).notNull,
|
||||||
|
)
|
||||||
|
.withForeignKey('dataStoreId', {
|
||||||
|
tableName: TABLE_TABLE_NAME_BEFORE,
|
||||||
|
columnName: 'id',
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
.withUniqueConstraintOn(['dataStoreId', 'name']).withTimestamps;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -94,6 +94,7 @@ import { LinkRoleToUserTable1750252139168 } from '../common/1750252139168-LinkRo
|
|||||||
import { RemoveOldRoleColumn1750252139170 } from '../common/1750252139170-RemoveOldRoleColumn';
|
import { RemoveOldRoleColumn1750252139170 } from '../common/1750252139170-RemoveOldRoleColumn';
|
||||||
import { AddInputsOutputsToTestCaseExecution1752669793000 } from '../common/1752669793000-AddInputsOutputsToTestCaseExecution';
|
import { AddInputsOutputsToTestCaseExecution1752669793000 } from '../common/1752669793000-AddInputsOutputsToTestCaseExecution';
|
||||||
import { CreateDataStoreTables1754475614601 } from '../common/1754475614601-CreateDataStoreTables';
|
import { CreateDataStoreTables1754475614601 } from '../common/1754475614601-CreateDataStoreTables';
|
||||||
|
import { ReplaceDataStoreTablesWithDataTables1754475614602 } from '../common/1754475614602-ReplaceDataStoreTablesWithDataTables';
|
||||||
import type { Migration } from '../migration-types';
|
import type { Migration } from '../migration-types';
|
||||||
import { UpdateParentFolderIdColumn1740445074052 } from '../mysqldb/1740445074052-UpdateParentFolderIdColumn';
|
import { UpdateParentFolderIdColumn1740445074052 } from '../mysqldb/1740445074052-UpdateParentFolderIdColumn';
|
||||||
|
|
||||||
@@ -195,4 +196,5 @@ export const mysqlMigrations: Migration[] = [
|
|||||||
AddInputsOutputsToTestCaseExecution1752669793000,
|
AddInputsOutputsToTestCaseExecution1752669793000,
|
||||||
CreateDataStoreTables1754475614601,
|
CreateDataStoreTables1754475614601,
|
||||||
RemoveOldRoleColumn1750252139170,
|
RemoveOldRoleColumn1750252139170,
|
||||||
|
ReplaceDataStoreTablesWithDataTables1754475614602,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ import { AddRolesTables1750252139167 } from '../common/1750252139167-AddRolesTab
|
|||||||
import { LinkRoleToUserTable1750252139168 } from '../common/1750252139168-LinkRoleToUserTable';
|
import { LinkRoleToUserTable1750252139168 } from '../common/1750252139168-LinkRoleToUserTable';
|
||||||
import { RemoveOldRoleColumn1750252139170 } from '../common/1750252139170-RemoveOldRoleColumn';
|
import { RemoveOldRoleColumn1750252139170 } from '../common/1750252139170-RemoveOldRoleColumn';
|
||||||
import { CreateDataStoreTables1754475614601 } from '../common/1754475614601-CreateDataStoreTables';
|
import { CreateDataStoreTables1754475614601 } from '../common/1754475614601-CreateDataStoreTables';
|
||||||
|
import { ReplaceDataStoreTablesWithDataTables1754475614602 } from '../common/1754475614602-ReplaceDataStoreTablesWithDataTables';
|
||||||
import type { Migration } from '../migration-types';
|
import type { Migration } from '../migration-types';
|
||||||
|
|
||||||
export const postgresMigrations: Migration[] = [
|
export const postgresMigrations: Migration[] = [
|
||||||
@@ -193,4 +194,5 @@ export const postgresMigrations: Migration[] = [
|
|||||||
AddInputsOutputsToTestCaseExecution1752669793000,
|
AddInputsOutputsToTestCaseExecution1752669793000,
|
||||||
CreateDataStoreTables1754475614601,
|
CreateDataStoreTables1754475614601,
|
||||||
RemoveOldRoleColumn1750252139170,
|
RemoveOldRoleColumn1750252139170,
|
||||||
|
ReplaceDataStoreTablesWithDataTables1754475614602,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ import { LinkRoleToUserTable1750252139168 } from '../common/1750252139168-LinkRo
|
|||||||
import { RemoveOldRoleColumn1750252139170 } from '../common/1750252139170-RemoveOldRoleColumn';
|
import { RemoveOldRoleColumn1750252139170 } from '../common/1750252139170-RemoveOldRoleColumn';
|
||||||
import { AddInputsOutputsToTestCaseExecution1752669793000 } from '../common/1752669793000-AddInputsOutputsToTestCaseExecution';
|
import { AddInputsOutputsToTestCaseExecution1752669793000 } from '../common/1752669793000-AddInputsOutputsToTestCaseExecution';
|
||||||
import { CreateDataStoreTables1754475614601 } from '../common/1754475614601-CreateDataStoreTables';
|
import { CreateDataStoreTables1754475614601 } from '../common/1754475614601-CreateDataStoreTables';
|
||||||
|
import { ReplaceDataStoreTablesWithDataTables1754475614602 } from '../common/1754475614602-ReplaceDataStoreTablesWithDataTables';
|
||||||
import type { Migration } from '../migration-types';
|
import type { Migration } from '../migration-types';
|
||||||
|
|
||||||
const sqliteMigrations: Migration[] = [
|
const sqliteMigrations: Migration[] = [
|
||||||
@@ -187,6 +188,7 @@ const sqliteMigrations: Migration[] = [
|
|||||||
AddInputsOutputsToTestCaseExecution1752669793000,
|
AddInputsOutputsToTestCaseExecution1752669793000,
|
||||||
CreateDataStoreTables1754475614601,
|
CreateDataStoreTables1754475614601,
|
||||||
RemoveOldRoleColumn1750252139170,
|
RemoveOldRoleColumn1750252139170,
|
||||||
|
ReplaceDataStoreTablesWithDataTables1754475614602,
|
||||||
];
|
];
|
||||||
|
|
||||||
export { sqliteMigrations };
|
export { sqliteMigrations };
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ beforeAll(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await testDb.truncate(['DataStore', 'DataStoreColumn', 'Project', 'ProjectRelation']);
|
await testDb.truncate(['DataTable', 'DataTableColumn', 'Project', 'ProjectRelation']);
|
||||||
|
|
||||||
owner = await createOwner();
|
owner = await createOwner();
|
||||||
member = await createMember();
|
member = await createMember();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ beforeAll(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await testDb.truncate(['DataStore', 'DataStoreColumn']);
|
await testDb.truncate(['DataTable', 'DataTableColumn']);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ beforeAll(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await testDb.truncate(['DataStore', 'DataStoreColumn', 'Project', 'ProjectRelation']);
|
await testDb.truncate(['DataTable', 'DataTableColumn', 'Project', 'ProjectRelation']);
|
||||||
|
|
||||||
projectRepository = Container.get(ProjectRepository);
|
projectRepository = Container.get(ProjectRepository);
|
||||||
dataStoreRepository = Container.get(DataStoreRepository);
|
dataStoreRepository = Container.get(DataStoreRepository);
|
||||||
@@ -758,7 +758,7 @@ describe('DELETE /projects/:projectId/data-stores/:dataStoreId', () => {
|
|||||||
expect(dataStoreInDb).toBeNull();
|
expect(dataStoreInDb).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should delete data from 'data_store', 'data_store_column' tables and drop 'data_store_user_<id>' table", async () => {
|
test("should delete data from 'data_table', 'data_table_column' tables and drop 'data_table_user_<id>' table", async () => {
|
||||||
const personalProject = await projectRepository.getPersonalProjectForUserOrFail(owner.id);
|
const personalProject = await projectRepository.getPersonalProjectForUserOrFail(owner.id);
|
||||||
const dataStore = await createDataStore(personalProject, {
|
const dataStore = await createDataStore(personalProject, {
|
||||||
name: 'Test Data Store',
|
name: 'Test Data Store',
|
||||||
@@ -779,7 +779,7 @@ describe('DELETE /projects/:projectId/data-stores/:dataStoreId', () => {
|
|||||||
expect(dataStoreInDb).toBeNull();
|
expect(dataStoreInDb).toBeNull();
|
||||||
|
|
||||||
const dataStoreColumnInDb = await dataStoreColumnRepository.findOneBy({
|
const dataStoreColumnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
});
|
});
|
||||||
expect(dataStoreColumnInDb).toBeNull();
|
expect(dataStoreColumnInDb).toBeNull();
|
||||||
|
|
||||||
@@ -924,7 +924,7 @@ describe('POST /projects/:projectId/data-stores/:dataStoreId/columns', () => {
|
|||||||
.send(payload)
|
.send(payload)
|
||||||
.expect(400);
|
.expect(400);
|
||||||
|
|
||||||
const columnsInDb = await dataStoreColumnRepository.findBy({ dataStoreId: dataStore.id });
|
const columnsInDb = await dataStoreColumnRepository.findBy({ dataTableId: dataStore.id });
|
||||||
expect(columnsInDb).toHaveLength(0);
|
expect(columnsInDb).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -942,7 +942,7 @@ describe('POST /projects/:projectId/data-stores/:dataStoreId/columns', () => {
|
|||||||
.send(payload)
|
.send(payload)
|
||||||
.expect(400);
|
.expect(400);
|
||||||
|
|
||||||
const columnsInDb = await dataStoreColumnRepository.findBy({ dataStoreId: dataStore.id });
|
const columnsInDb = await dataStoreColumnRepository.findBy({ dataTableId: dataStore.id });
|
||||||
expect(columnsInDb).toHaveLength(0);
|
expect(columnsInDb).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -964,7 +964,7 @@ describe('POST /projects/:projectId/data-stores/:dataStoreId/columns', () => {
|
|||||||
})
|
})
|
||||||
.expect(403);
|
.expect(403);
|
||||||
|
|
||||||
const columnsInDb = await dataStoreColumnRepository.findBy({ dataStoreId: dataStore.id });
|
const columnsInDb = await dataStoreColumnRepository.findBy({ dataTableId: dataStore.id });
|
||||||
expect(columnsInDb).toHaveLength(1);
|
expect(columnsInDb).toHaveLength(1);
|
||||||
expect(columnsInDb[0].name).toBe('test-column');
|
expect(columnsInDb[0].name).toBe('test-column');
|
||||||
});
|
});
|
||||||
@@ -984,7 +984,7 @@ describe('POST /projects/:projectId/data-stores/:dataStoreId/columns', () => {
|
|||||||
.send(payload)
|
.send(payload)
|
||||||
.expect(403);
|
.expect(403);
|
||||||
|
|
||||||
const columnsInDb = await dataStoreColumnRepository.findBy({ dataStoreId: dataStore.id });
|
const columnsInDb = await dataStoreColumnRepository.findBy({ dataTableId: dataStore.id });
|
||||||
expect(columnsInDb).toHaveLength(0);
|
expect(columnsInDb).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1011,7 +1011,7 @@ describe('POST /projects/:projectId/data-stores/:dataStoreId/columns', () => {
|
|||||||
.send(payload)
|
.send(payload)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnsInDb = await dataStoreColumnRepository.findBy({ dataStoreId: dataStore.id });
|
const columnsInDb = await dataStoreColumnRepository.findBy({ dataTableId: dataStore.id });
|
||||||
expect(columnsInDb).toHaveLength(2);
|
expect(columnsInDb).toHaveLength(2);
|
||||||
expect(columnsInDb[0].name).toBe('new-column');
|
expect(columnsInDb[0].name).toBe('new-column');
|
||||||
expect(columnsInDb[0].type).toBe('string');
|
expect(columnsInDb[0].type).toBe('string');
|
||||||
@@ -1040,7 +1040,7 @@ describe('POST /projects/:projectId/data-stores/:dataStoreId/columns', () => {
|
|||||||
.send(payload)
|
.send(payload)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnsInDb = await dataStoreColumnRepository.findBy({ dataStoreId: dataStore.id });
|
const columnsInDb = await dataStoreColumnRepository.findBy({ dataTableId: dataStore.id });
|
||||||
expect(columnsInDb).toHaveLength(2);
|
expect(columnsInDb).toHaveLength(2);
|
||||||
expect(columnsInDb[0].name).toBe('new-column');
|
expect(columnsInDb[0].name).toBe('new-column');
|
||||||
expect(columnsInDb[0].type).toBe('boolean');
|
expect(columnsInDb[0].type).toBe('boolean');
|
||||||
@@ -1070,7 +1070,7 @@ describe('POST /projects/:projectId/data-stores/:dataStoreId/columns', () => {
|
|||||||
.send(payload)
|
.send(payload)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnsInDb = await dataStoreColumnRepository.findBy({ dataStoreId: dataStore.id });
|
const columnsInDb = await dataStoreColumnRepository.findBy({ dataTableId: dataStore.id });
|
||||||
expect(columnsInDb).toHaveLength(2);
|
expect(columnsInDb).toHaveLength(2);
|
||||||
expect(columnsInDb[0].name).toBe('new-column');
|
expect(columnsInDb[0].name).toBe('new-column');
|
||||||
expect(columnsInDb[0].type).toBe('boolean');
|
expect(columnsInDb[0].type).toBe('boolean');
|
||||||
@@ -1163,7 +1163,7 @@ describe('DELETE /projects/:projectId/data-stores/:dataStoreId/columns/:columnId
|
|||||||
.expect(403);
|
.expect(403);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
});
|
});
|
||||||
expect(columnInDb).toBeDefined();
|
expect(columnInDb).toBeDefined();
|
||||||
@@ -1187,7 +1187,7 @@ describe('DELETE /projects/:projectId/data-stores/:dataStoreId/columns/:columnId
|
|||||||
.expect(403);
|
.expect(403);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
});
|
});
|
||||||
expect(columnInDb).toBeDefined();
|
expect(columnInDb).toBeDefined();
|
||||||
@@ -1214,7 +1214,7 @@ describe('DELETE /projects/:projectId/data-stores/:dataStoreId/columns/:columnId
|
|||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
});
|
});
|
||||||
expect(columnInDb).toBeNull();
|
expect(columnInDb).toBeNull();
|
||||||
@@ -1240,7 +1240,7 @@ describe('DELETE /projects/:projectId/data-stores/:dataStoreId/columns/:columnId
|
|||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
});
|
});
|
||||||
expect(columnInDb).toBeNull();
|
expect(columnInDb).toBeNull();
|
||||||
@@ -1265,7 +1265,7 @@ describe('DELETE /projects/:projectId/data-stores/:dataStoreId/columns/:columnId
|
|||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
});
|
});
|
||||||
expect(columnInDb).toBeNull();
|
expect(columnInDb).toBeNull();
|
||||||
@@ -1289,7 +1289,7 @@ describe('DELETE /projects/:projectId/data-stores/:dataStoreId/columns/:columnId
|
|||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
});
|
});
|
||||||
expect(columnInDb).toBeNull();
|
expect(columnInDb).toBeNull();
|
||||||
@@ -1364,7 +1364,7 @@ describe('PATCH /projects/:projectId/data-stores/:dataStoreId/columns/:columnId/
|
|||||||
.expect(403);
|
.expect(403);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
index: 0,
|
index: 0,
|
||||||
});
|
});
|
||||||
@@ -1395,7 +1395,7 @@ describe('PATCH /projects/:projectId/data-stores/:dataStoreId/columns/:columnId/
|
|||||||
.expect(403);
|
.expect(403);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
index: 0,
|
index: 0,
|
||||||
});
|
});
|
||||||
@@ -1426,7 +1426,7 @@ describe('PATCH /projects/:projectId/data-stores/:dataStoreId/columns/:columnId/
|
|||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
index: 1,
|
index: 1,
|
||||||
});
|
});
|
||||||
@@ -1457,7 +1457,7 @@ describe('PATCH /projects/:projectId/data-stores/:dataStoreId/columns/:columnId/
|
|||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
index: 1,
|
index: 1,
|
||||||
});
|
});
|
||||||
@@ -1488,7 +1488,7 @@ describe('PATCH /projects/:projectId/data-stores/:dataStoreId/columns/:columnId/
|
|||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
index: 1,
|
index: 1,
|
||||||
});
|
});
|
||||||
@@ -1517,7 +1517,7 @@ describe('PATCH /projects/:projectId/data-stores/:dataStoreId/columns/:columnId/
|
|||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
const columnInDb = await dataStoreColumnRepository.findOneBy({
|
||||||
dataStoreId: dataStore.id,
|
dataTableId: dataStore.id,
|
||||||
name: 'test-column',
|
name: 'test-column',
|
||||||
index: 1,
|
index: 1,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ beforeAll(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await testDb.truncate(['DataStore', 'DataStoreColumn']);
|
await testDb.truncate(['DataTable', 'DataTableColumn']);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@@ -52,17 +52,17 @@ describe('dataStore', () => {
|
|||||||
|
|
||||||
describe('createDataStore', () => {
|
describe('createDataStore', () => {
|
||||||
it('should create a columns table and a user table if columns are provided', async () => {
|
it('should create a columns table and a user table if columns are provided', async () => {
|
||||||
const { id: dataStoreId } = await dataStoreService.createDataStore(project1.id, {
|
const { id: dataTableId } = await dataStoreService.createDataStore(project1.id, {
|
||||||
name: 'dataStoreWithColumns',
|
name: 'dataStoreWithColumns',
|
||||||
columns: [{ name: 'foo', type: 'string' }],
|
columns: [{ name: 'foo', type: 'string' }],
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(dataStoreService.getColumns(dataStoreId, project1.id)).resolves.toEqual([
|
await expect(dataStoreService.getColumns(dataTableId, project1.id)).resolves.toEqual([
|
||||||
{
|
{
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
index: 0,
|
index: 0,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
createdAt: expect.any(Date),
|
createdAt: expect.any(Date),
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(Date),
|
||||||
@@ -70,7 +70,7 @@ describe('dataStore', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// Select the column from user table to check for its existence
|
// Select the column from user table to check for its existence
|
||||||
const userTableName = dataStoreRowsRepository.toTableName(dataStoreId);
|
const userTableName = dataStoreRowsRepository.toTableName(dataTableId);
|
||||||
const rows = await dataStoreRepository.manager
|
const rows = await dataStoreRepository.manager
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
.select('foo')
|
.select('foo')
|
||||||
@@ -251,7 +251,7 @@ describe('dataStore', () => {
|
|||||||
it('should succeed with adding columns to a non-empty table as well as to a user table', async () => {
|
it('should succeed with adding columns to a non-empty table as well as to a user table', async () => {
|
||||||
const existingColumns: CreateDataStoreColumnDto[] = [{ name: 'myColumn0', type: 'string' }];
|
const existingColumns: CreateDataStoreColumnDto[] = [{ name: 'myColumn0', type: 'string' }];
|
||||||
|
|
||||||
const { id: dataStoreId } = await dataStoreService.createDataStore(project1.id, {
|
const { id: dataTableId } = await dataStoreService.createDataStore(project1.id, {
|
||||||
name: 'dataStoreWithColumns',
|
name: 'dataStoreWithColumns',
|
||||||
columns: existingColumns,
|
columns: existingColumns,
|
||||||
});
|
});
|
||||||
@@ -264,45 +264,45 @@ describe('dataStore', () => {
|
|||||||
];
|
];
|
||||||
for (const column of columns) {
|
for (const column of columns) {
|
||||||
// ACT
|
// ACT
|
||||||
const result = await dataStoreService.addColumn(dataStoreId, project1.id, column);
|
const result = await dataStoreService.addColumn(dataTableId, project1.id, column);
|
||||||
// ASSERT
|
// ASSERT
|
||||||
expect(result).toMatchObject(column);
|
expect(result).toMatchObject(column);
|
||||||
}
|
}
|
||||||
const columnResult = await dataStoreService.getColumns(dataStoreId, project1.id);
|
const columnResult = await dataStoreService.getColumns(dataTableId, project1.id);
|
||||||
expect(columnResult).toEqual([
|
expect(columnResult).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
index: 0,
|
index: 0,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
name: 'myColumn0',
|
name: 'myColumn0',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
index: 1,
|
index: 1,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
name: 'myColumn1',
|
name: 'myColumn1',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
index: 2,
|
index: 2,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
name: 'myColumn2',
|
name: 'myColumn2',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
index: 3,
|
index: 3,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
name: 'myColumn3',
|
name: 'myColumn3',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
index: 4,
|
index: 4,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
name: 'myColumn4',
|
name: 'myColumn4',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const userTableName = dataStoreRowsRepository.toTableName(dataStoreId);
|
const userTableName = dataStoreRowsRepository.toTableName(dataTableId);
|
||||||
const queryRunner = dataStoreRepository.manager.connection.createQueryRunner();
|
const queryRunner = dataStoreRepository.manager.connection.createQueryRunner();
|
||||||
try {
|
try {
|
||||||
const table = await queryRunner.getTable(userTableName);
|
const table = await queryRunner.getTable(userTableName);
|
||||||
@@ -326,7 +326,7 @@ describe('dataStore', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed with adding columns to an empty table', async () => {
|
it('should succeed with adding columns to an empty table', async () => {
|
||||||
const { id: dataStoreId } = await dataStoreService.createDataStore(project1.id, {
|
const { id: dataTableId } = await dataStoreService.createDataStore(project1.id, {
|
||||||
name: 'dataStore',
|
name: 'dataStore',
|
||||||
columns: [],
|
columns: [],
|
||||||
});
|
});
|
||||||
@@ -337,29 +337,29 @@ describe('dataStore', () => {
|
|||||||
];
|
];
|
||||||
for (const column of columns) {
|
for (const column of columns) {
|
||||||
// ACT
|
// ACT
|
||||||
const result = await dataStoreService.addColumn(dataStoreId, project1.id, column);
|
const result = await dataStoreService.addColumn(dataTableId, project1.id, column);
|
||||||
// ASSERT
|
// ASSERT
|
||||||
expect(result).toMatchObject(column);
|
expect(result).toMatchObject(column);
|
||||||
}
|
}
|
||||||
const columnResult = await dataStoreService.getColumns(dataStoreId, project1.id);
|
const columnResult = await dataStoreService.getColumns(dataTableId, project1.id);
|
||||||
expect(columnResult.length).toBe(2);
|
expect(columnResult.length).toBe(2);
|
||||||
|
|
||||||
expect(columnResult).toEqual([
|
expect(columnResult).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
index: 0,
|
index: 0,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
name: 'myColumn0',
|
name: 'myColumn0',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
index: 1,
|
index: 1,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
name: 'myColumn1',
|
name: 'myColumn1',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const userTableName = dataStoreRowsRepository.toTableName(dataStoreId);
|
const userTableName = dataStoreRowsRepository.toTableName(dataTableId);
|
||||||
const queryRunner = dataStoreRepository.manager.connection.createQueryRunner();
|
const queryRunner = dataStoreRepository.manager.connection.createQueryRunner();
|
||||||
try {
|
try {
|
||||||
const table = await queryRunner.getTable(userTableName);
|
const table = await queryRunner.getTable(userTableName);
|
||||||
@@ -516,31 +516,31 @@ describe('dataStore', () => {
|
|||||||
describe('deleteColumn', () => {
|
describe('deleteColumn', () => {
|
||||||
it('should succeed with deleting a column', async () => {
|
it('should succeed with deleting a column', async () => {
|
||||||
// ARRANGE
|
// ARRANGE
|
||||||
const { id: dataStoreId } = await dataStoreService.createDataStore(project1.id, {
|
const { id: dataTableId } = await dataStoreService.createDataStore(project1.id, {
|
||||||
name: 'dataStore',
|
name: 'dataStore',
|
||||||
columns: [],
|
columns: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const c1 = await dataStoreService.addColumn(dataStoreId, project1.id, {
|
const c1 = await dataStoreService.addColumn(dataTableId, project1.id, {
|
||||||
name: 'myColumn1',
|
name: 'myColumn1',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
});
|
});
|
||||||
const c2 = await dataStoreService.addColumn(dataStoreId, project1.id, {
|
const c2 = await dataStoreService.addColumn(dataTableId, project1.id, {
|
||||||
name: 'myColumn2',
|
name: 'myColumn2',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
});
|
});
|
||||||
|
|
||||||
// ACT
|
// ACT
|
||||||
const result = await dataStoreService.deleteColumn(dataStoreId, project1.id, c1.id);
|
const result = await dataStoreService.deleteColumn(dataTableId, project1.id, c1.id);
|
||||||
|
|
||||||
// ASSERT
|
// ASSERT
|
||||||
expect(result).toEqual(true);
|
expect(result).toEqual(true);
|
||||||
|
|
||||||
const columns = await dataStoreService.getColumns(dataStoreId, project1.id);
|
const columns = await dataStoreService.getColumns(dataTableId, project1.id);
|
||||||
expect(columns).toEqual([
|
expect(columns).toEqual([
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
id: c2.id,
|
id: c2.id,
|
||||||
name: 'myColumn2',
|
name: 'myColumn2',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
@@ -591,40 +591,40 @@ describe('dataStore', () => {
|
|||||||
describe('moveColumn', () => {
|
describe('moveColumn', () => {
|
||||||
it('should succeed with moving a column', async () => {
|
it('should succeed with moving a column', async () => {
|
||||||
// ARRANGE
|
// ARRANGE
|
||||||
const { id: dataStoreId } = await dataStoreService.createDataStore(project1.id, {
|
const { id: dataTableId } = await dataStoreService.createDataStore(project1.id, {
|
||||||
name: 'dataStore',
|
name: 'dataStore',
|
||||||
columns: [],
|
columns: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const c1 = await dataStoreService.addColumn(dataStoreId, project1.id, {
|
const c1 = await dataStoreService.addColumn(dataTableId, project1.id, {
|
||||||
name: 'myColumn1',
|
name: 'myColumn1',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
});
|
});
|
||||||
const c2 = await dataStoreService.addColumn(dataStoreId, project1.id, {
|
const c2 = await dataStoreService.addColumn(dataTableId, project1.id, {
|
||||||
name: 'myColumn2',
|
name: 'myColumn2',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
});
|
});
|
||||||
|
|
||||||
// ACT
|
// ACT
|
||||||
const result = await dataStoreService.moveColumn(dataStoreId, project1.id, c2.id, {
|
const result = await dataStoreService.moveColumn(dataTableId, project1.id, c2.id, {
|
||||||
targetIndex: 0,
|
targetIndex: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
// ASSERT
|
// ASSERT
|
||||||
expect(result).toEqual(true);
|
expect(result).toEqual(true);
|
||||||
|
|
||||||
const columns = await dataStoreService.getColumns(dataStoreId, project1.id);
|
const columns = await dataStoreService.getColumns(dataTableId, project1.id);
|
||||||
expect(columns).toMatchObject([
|
expect(columns).toMatchObject([
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
id: c2.id,
|
id: c2.id,
|
||||||
name: 'myColumn2',
|
name: 'myColumn2',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
index: 1,
|
index: 1,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
id: c1.id,
|
id: c1.id,
|
||||||
name: 'myColumn1',
|
name: 'myColumn1',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|||||||
@@ -5,50 +5,50 @@ import { addColumnQuery, deleteColumnQuery, splitRowsByExistence } from '../util
|
|||||||
describe('sql-utils', () => {
|
describe('sql-utils', () => {
|
||||||
describe('addColumnQuery', () => {
|
describe('addColumnQuery', () => {
|
||||||
it('should generate a valid SQL query for adding columns to a table, sqlite', () => {
|
it('should generate a valid SQL query for adding columns to a table, sqlite', () => {
|
||||||
const tableName = 'data_store_user_abc';
|
const tableName = 'data_table_user_abc';
|
||||||
const column = { name: 'email', type: 'number' as const };
|
const column = { name: 'email', type: 'number' as const };
|
||||||
|
|
||||||
const query = addColumnQuery(tableName, column, 'sqlite');
|
const query = addColumnQuery(tableName, column, 'sqlite');
|
||||||
|
|
||||||
expect(query).toBe('ALTER TABLE "data_store_user_abc" ADD "email" REAL');
|
expect(query).toBe('ALTER TABLE "data_table_user_abc" ADD "email" REAL');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a valid SQL query for adding columns to a table, postgres', () => {
|
it('should generate a valid SQL query for adding columns to a table, postgres', () => {
|
||||||
const tableName = 'data_store_user_abc';
|
const tableName = 'data_table_user_abc';
|
||||||
const column = { name: 'email', type: 'number' as const };
|
const column = { name: 'email', type: 'number' as const };
|
||||||
|
|
||||||
const query = addColumnQuery(tableName, column, 'postgres');
|
const query = addColumnQuery(tableName, column, 'postgres');
|
||||||
|
|
||||||
expect(query).toBe('ALTER TABLE "data_store_user_abc" ADD "email" DOUBLE PRECISION');
|
expect(query).toBe('ALTER TABLE "data_table_user_abc" ADD "email" DOUBLE PRECISION');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a valid SQL query for adding columns to a table, mysql', () => {
|
it('should generate a valid SQL query for adding columns to a table, mysql', () => {
|
||||||
const tableName = 'data_store_user_abc';
|
const tableName = 'data_table_user_abc';
|
||||||
const column = { name: 'email', type: 'number' as const };
|
const column = { name: 'email', type: 'number' as const };
|
||||||
|
|
||||||
const query = addColumnQuery(tableName, column, 'mysql');
|
const query = addColumnQuery(tableName, column, 'mysql');
|
||||||
|
|
||||||
expect(query).toBe('ALTER TABLE `data_store_user_abc` ADD `email` DOUBLE');
|
expect(query).toBe('ALTER TABLE `data_table_user_abc` ADD `email` DOUBLE');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a valid SQL query for adding columns to a table, mariadb', () => {
|
it('should generate a valid SQL query for adding columns to a table, mariadb', () => {
|
||||||
const tableName = 'data_store_user_abc';
|
const tableName = 'data_table_user_abc';
|
||||||
const column = { name: 'email', type: 'number' as const };
|
const column = { name: 'email', type: 'number' as const };
|
||||||
|
|
||||||
const query = addColumnQuery(tableName, column, 'mariadb');
|
const query = addColumnQuery(tableName, column, 'mariadb');
|
||||||
|
|
||||||
expect(query).toBe('ALTER TABLE `data_store_user_abc` ADD `email` DOUBLE');
|
expect(query).toBe('ALTER TABLE `data_table_user_abc` ADD `email` DOUBLE');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deleteColumnQuery', () => {
|
describe('deleteColumnQuery', () => {
|
||||||
it('should generate a valid SQL query for deleting columns from a table', () => {
|
it('should generate a valid SQL query for deleting columns from a table', () => {
|
||||||
const tableName = 'data_store_user_abc';
|
const tableName = 'data_table_user_abc';
|
||||||
const column = 'email';
|
const column = 'email';
|
||||||
|
|
||||||
const query = deleteColumnQuery(tableName, column, 'sqlite');
|
const query = deleteColumnQuery(tableName, column, 'sqlite');
|
||||||
|
|
||||||
expect(query).toBe('ALTER TABLE "data_store_user_abc" DROP COLUMN "email"');
|
expect(query).toBe('ALTER TABLE "data_table_user_abc" DROP COLUMN "email"');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,25 +3,25 @@ import { Service } from '@n8n/di';
|
|||||||
import { DataSource, EntityManager, Repository } from '@n8n/typeorm';
|
import { DataSource, EntityManager, Repository } from '@n8n/typeorm';
|
||||||
import { UnexpectedError } from 'n8n-workflow';
|
import { UnexpectedError } from 'n8n-workflow';
|
||||||
|
|
||||||
import { DataStoreColumn } from './data-store-column.entity';
|
|
||||||
import { DataStoreRowsRepository } from './data-store-rows.repository';
|
import { DataStoreRowsRepository } from './data-store-rows.repository';
|
||||||
|
import { DataTableColumn } from './data-table-column.entity';
|
||||||
import { DataStoreColumnNameConflictError } from './errors/data-store-column-name-conflict.error';
|
import { DataStoreColumnNameConflictError } from './errors/data-store-column-name-conflict.error';
|
||||||
import { DataStoreValidationError } from './errors/data-store-validation.error';
|
import { DataStoreValidationError } from './errors/data-store-validation.error';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class DataStoreColumnRepository extends Repository<DataStoreColumn> {
|
export class DataStoreColumnRepository extends Repository<DataTableColumn> {
|
||||||
constructor(
|
constructor(
|
||||||
dataSource: DataSource,
|
dataSource: DataSource,
|
||||||
private dataStoreRowsRepository: DataStoreRowsRepository,
|
private dataStoreRowsRepository: DataStoreRowsRepository,
|
||||||
) {
|
) {
|
||||||
super(DataStoreColumn, dataSource.manager);
|
super(DataTableColumn, dataSource.manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getColumns(rawDataStoreId: string, em?: EntityManager) {
|
async getColumns(dataTableId: string, em?: EntityManager) {
|
||||||
const executor = em ?? this.manager;
|
const executor = em ?? this.manager;
|
||||||
const columns = await executor
|
const columns = await executor
|
||||||
.createQueryBuilder(DataStoreColumn, 'dsc')
|
.createQueryBuilder(DataTableColumn, 'dsc')
|
||||||
.where('dsc.dataStoreId = :dataStoreId', { dataStoreId: rawDataStoreId })
|
.where('dsc.dataTableId = :dataTableId', { dataTableId })
|
||||||
.getMany();
|
.getMany();
|
||||||
|
|
||||||
// Ensure columns are always returned in the correct order by index,
|
// Ensure columns are always returned in the correct order by index,
|
||||||
@@ -32,30 +32,30 @@ export class DataStoreColumnRepository extends Repository<DataStoreColumn> {
|
|||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
async addColumn(dataStoreId: string, schema: DataStoreCreateColumnSchema) {
|
async addColumn(dataTableId: string, schema: DataStoreCreateColumnSchema) {
|
||||||
return await this.manager.transaction(async (em) => {
|
return await this.manager.transaction(async (em) => {
|
||||||
const existingColumnMatch = await em.existsBy(DataStoreColumn, {
|
const existingColumnMatch = await em.existsBy(DataTableColumn, {
|
||||||
name: schema.name,
|
name: schema.name,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existingColumnMatch) {
|
if (existingColumnMatch) {
|
||||||
throw new DataStoreColumnNameConflictError(schema.name, dataStoreId);
|
throw new DataStoreColumnNameConflictError(schema.name, dataTableId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema.index === undefined) {
|
if (schema.index === undefined) {
|
||||||
const columns = await this.getColumns(dataStoreId, em);
|
const columns = await this.getColumns(dataTableId, em);
|
||||||
schema.index = columns.length;
|
schema.index = columns.length;
|
||||||
} else {
|
} else {
|
||||||
await this.shiftColumns(dataStoreId, schema.index, 1, em);
|
await this.shiftColumns(dataTableId, schema.index, 1, em);
|
||||||
}
|
}
|
||||||
|
|
||||||
const column = em.create(DataStoreColumn, {
|
const column = em.create(DataTableColumn, {
|
||||||
...schema,
|
...schema,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await em.insert(DataStoreColumn, column);
|
await em.insert(DataTableColumn, column);
|
||||||
|
|
||||||
const queryRunner = em.queryRunner;
|
const queryRunner = em.queryRunner;
|
||||||
if (!queryRunner) {
|
if (!queryRunner) {
|
||||||
@@ -63,7 +63,7 @@ export class DataStoreColumnRepository extends Repository<DataStoreColumn> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.dataStoreRowsRepository.addColumn(
|
await this.dataStoreRowsRepository.addColumn(
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
column,
|
column,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
em.connection.options.type,
|
em.connection.options.type,
|
||||||
@@ -73,9 +73,9 @@ export class DataStoreColumnRepository extends Repository<DataStoreColumn> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteColumn(dataStoreId: string, column: DataStoreColumn) {
|
async deleteColumn(dataStoreId: string, column: DataTableColumn) {
|
||||||
await this.manager.transaction(async (em) => {
|
await this.manager.transaction(async (em) => {
|
||||||
await em.remove(DataStoreColumn, column);
|
await em.remove(DataTableColumn, column);
|
||||||
|
|
||||||
const queryRunner = em.queryRunner;
|
const queryRunner = em.queryRunner;
|
||||||
if (!queryRunner) {
|
if (!queryRunner) {
|
||||||
@@ -92,9 +92,9 @@ export class DataStoreColumnRepository extends Repository<DataStoreColumn> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async moveColumn(dataStoreId: string, column: DataStoreColumn, targetIndex: number) {
|
async moveColumn(dataTableId: string, column: DataTableColumn, targetIndex: number) {
|
||||||
await this.manager.transaction(async (em) => {
|
await this.manager.transaction(async (em) => {
|
||||||
const columnCount = await em.countBy(DataStoreColumn, { dataStoreId });
|
const columnCount = await em.countBy(DataTableColumn, { dataTableId });
|
||||||
|
|
||||||
if (targetIndex < 0) {
|
if (targetIndex < 0) {
|
||||||
throw new DataStoreValidationError('tried to move column to negative index');
|
throw new DataStoreValidationError('tried to move column to negative index');
|
||||||
@@ -106,27 +106,22 @@ export class DataStoreColumnRepository extends Repository<DataStoreColumn> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.shiftColumns(dataStoreId, column.index, -1, em);
|
await this.shiftColumns(dataTableId, column.index, -1, em);
|
||||||
await this.shiftColumns(dataStoreId, targetIndex, 1, em);
|
await this.shiftColumns(dataTableId, targetIndex, 1, em);
|
||||||
await em.update(DataStoreColumn, { id: column.id }, { index: targetIndex });
|
await em.update(DataTableColumn, { id: column.id }, { index: targetIndex });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async shiftColumns(
|
async shiftColumns(dataTableId: string, lowestIndex: number, delta: -1 | 1, em?: EntityManager) {
|
||||||
rawDataStoreId: string,
|
|
||||||
lowestIndex: number,
|
|
||||||
delta: -1 | 1,
|
|
||||||
em?: EntityManager,
|
|
||||||
) {
|
|
||||||
const executor = em ?? this.manager;
|
const executor = em ?? this.manager;
|
||||||
await executor
|
await executor
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
.update(DataStoreColumn)
|
.update(DataTableColumn)
|
||||||
.set({
|
.set({
|
||||||
index: () => `index + ${delta}`,
|
index: () => `index + ${delta}`,
|
||||||
})
|
})
|
||||||
.where('dataStoreId = :dataStoreId AND index >= :thresholdValue', {
|
.where('dataTableId = :dataTableId AND index >= :thresholdValue', {
|
||||||
dataStoreId: rawDataStoreId,
|
dataTableId,
|
||||||
thresholdValue: lowestIndex,
|
thresholdValue: lowestIndex,
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import {
|
|||||||
DATA_TABLE_SYSTEM_COLUMNS,
|
DATA_TABLE_SYSTEM_COLUMNS,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { DataStoreColumn } from './data-store-column.entity';
|
|
||||||
import { DataStoreUserTableName } from './data-store.types';
|
import { DataStoreUserTableName } from './data-store.types';
|
||||||
|
import { DataTableColumn } from './data-table-column.entity';
|
||||||
import {
|
import {
|
||||||
addColumnQuery,
|
addColumnQuery,
|
||||||
deleteColumnQuery,
|
deleteColumnQuery,
|
||||||
@@ -138,19 +138,19 @@ export class DataStoreRowsRepository {
|
|||||||
|
|
||||||
toTableName(dataStoreId: string): DataStoreUserTableName {
|
toTableName(dataStoreId: string): DataStoreUserTableName {
|
||||||
const { tablePrefix } = this.globalConfig.database;
|
const { tablePrefix } = this.globalConfig.database;
|
||||||
return `${tablePrefix}data_store_user_${dataStoreId}`;
|
return `${tablePrefix}data_table_user_${dataStoreId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async insertRows<T extends boolean | undefined>(
|
async insertRows<T extends boolean | undefined>(
|
||||||
dataStoreId: string,
|
dataStoreId: string,
|
||||||
rows: DataStoreRows,
|
rows: DataStoreRows,
|
||||||
columns: DataStoreColumn[],
|
columns: DataTableColumn[],
|
||||||
returnData?: T,
|
returnData?: T,
|
||||||
): Promise<Array<T extends true ? DataStoreRowReturn : Pick<DataStoreRowReturn, 'id'>>>;
|
): Promise<Array<T extends true ? DataStoreRowReturn : Pick<DataStoreRowReturn, 'id'>>>;
|
||||||
async insertRows(
|
async insertRows(
|
||||||
dataStoreId: string,
|
dataStoreId: string,
|
||||||
rows: DataStoreRows,
|
rows: DataStoreRows,
|
||||||
columns: DataStoreColumn[],
|
columns: DataTableColumn[],
|
||||||
returnData?: boolean,
|
returnData?: boolean,
|
||||||
): Promise<Array<DataStoreRowReturn | Pick<DataStoreRowReturn, 'id'>>> {
|
): Promise<Array<DataStoreRowReturn | Pick<DataStoreRowReturn, 'id'>>> {
|
||||||
const inserted: Array<Pick<DataStoreRowReturn, 'id'>> = [];
|
const inserted: Array<Pick<DataStoreRowReturn, 'id'>> = [];
|
||||||
@@ -217,7 +217,7 @@ export class DataStoreRowsRepository {
|
|||||||
dataStoreId: string,
|
dataStoreId: string,
|
||||||
setData: Record<string, DataStoreColumnJsType | null>,
|
setData: Record<string, DataStoreColumnJsType | null>,
|
||||||
whereData: Record<string, DataStoreColumnJsType | null>,
|
whereData: Record<string, DataStoreColumnJsType | null>,
|
||||||
columns: DataStoreColumn[],
|
columns: DataTableColumn[],
|
||||||
returnData: boolean = false,
|
returnData: boolean = false,
|
||||||
) {
|
) {
|
||||||
const dbType = this.dataSource.options.type;
|
const dbType = this.dataSource.options.type;
|
||||||
@@ -278,14 +278,14 @@ export class DataStoreRowsRepository {
|
|||||||
dataStoreId: string,
|
dataStoreId: string,
|
||||||
matchFields: string[],
|
matchFields: string[],
|
||||||
rows: DataStoreRows,
|
rows: DataStoreRows,
|
||||||
columns: DataStoreColumn[],
|
columns: DataTableColumn[],
|
||||||
returnData?: T,
|
returnData?: T,
|
||||||
): Promise<T extends true ? DataStoreRowReturn[] : true>;
|
): Promise<T extends true ? DataStoreRowReturn[] : true>;
|
||||||
async upsertRows(
|
async upsertRows(
|
||||||
dataStoreId: string,
|
dataStoreId: string,
|
||||||
matchFields: string[],
|
matchFields: string[],
|
||||||
rows: DataStoreRows,
|
rows: DataStoreRows,
|
||||||
columns: DataStoreColumn[],
|
columns: DataTableColumn[],
|
||||||
returnData?: boolean,
|
returnData?: boolean,
|
||||||
) {
|
) {
|
||||||
returnData = returnData ?? false;
|
returnData = returnData ?? false;
|
||||||
@@ -343,7 +343,7 @@ export class DataStoreRowsRepository {
|
|||||||
|
|
||||||
async createTableWithColumns(
|
async createTableWithColumns(
|
||||||
dataStoreId: string,
|
dataStoreId: string,
|
||||||
columns: DataStoreColumn[],
|
columns: DataTableColumn[],
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
) {
|
) {
|
||||||
const dslColumns = [new DslColumn('id').int.autoGenerate2.primary, ...toDslColumns(columns)];
|
const dslColumns = [new DslColumn('id').int.autoGenerate2.primary, ...toDslColumns(columns)];
|
||||||
@@ -360,7 +360,7 @@ export class DataStoreRowsRepository {
|
|||||||
|
|
||||||
async addColumn(
|
async addColumn(
|
||||||
dataStoreId: string,
|
dataStoreId: string,
|
||||||
column: DataStoreColumn,
|
column: DataTableColumn,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
dbType: DataSourceOptions['type'],
|
dbType: DataSourceOptions['type'],
|
||||||
) {
|
) {
|
||||||
@@ -387,7 +387,7 @@ export class DataStoreRowsRepository {
|
|||||||
return { count: count ?? -1, data };
|
return { count: count ?? -1, data };
|
||||||
}
|
}
|
||||||
|
|
||||||
async getManyByIds(dataStoreId: string, ids: number[], columns: DataStoreColumn[]) {
|
async getManyByIds(dataStoreId: string, ids: number[], columns: DataTableColumn[]) {
|
||||||
const table = this.toTableName(dataStoreId);
|
const table = this.toTableName(dataStoreId);
|
||||||
const escapedColumns = columns.map((c) => this.dataSource.driver.escape(c.name));
|
const escapedColumns = columns.map((c) => this.dataSource.driver.escape(c.name));
|
||||||
const escapedSystemColumns = DATA_TABLE_SYSTEM_COLUMNS.map((x) =>
|
const escapedSystemColumns = DATA_TABLE_SYSTEM_COLUMNS.map((x) =>
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ import { Service } from '@n8n/di';
|
|||||||
import { DataSource, EntityManager, Repository, SelectQueryBuilder } from '@n8n/typeorm';
|
import { DataSource, EntityManager, Repository, SelectQueryBuilder } from '@n8n/typeorm';
|
||||||
import { UnexpectedError } from 'n8n-workflow';
|
import { UnexpectedError } from 'n8n-workflow';
|
||||||
|
|
||||||
import { DataStoreColumn } from './data-store-column.entity';
|
|
||||||
import { DataStoreRowsRepository } from './data-store-rows.repository';
|
import { DataStoreRowsRepository } from './data-store-rows.repository';
|
||||||
import { DataStore } from './data-store.entity';
|
import { DataTableColumn } from './data-table-column.entity';
|
||||||
|
import { DataTable } from './data-table.entity';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class DataStoreRepository extends Repository<DataStore> {
|
export class DataStoreRepository extends Repository<DataTable> {
|
||||||
constructor(
|
constructor(
|
||||||
dataSource: DataSource,
|
dataSource: DataSource,
|
||||||
private dataStoreRowsRepository: DataStoreRowsRepository,
|
private dataStoreRowsRepository: DataStoreRowsRepository,
|
||||||
) {
|
) {
|
||||||
super(DataStore, dataSource.manager);
|
super(DataTable, dataSource.manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
async createDataStore(projectId: string, name: string, columns: DataStoreCreateColumnSchema[]) {
|
async createDataStore(projectId: string, name: string, columns: DataStoreCreateColumnSchema[]) {
|
||||||
@@ -25,11 +25,11 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
throw new UnexpectedError('bad column name');
|
throw new UnexpectedError('bad column name');
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataStoreId: string | undefined;
|
let dataTableId: string | undefined;
|
||||||
await this.manager.transaction(async (em) => {
|
await this.manager.transaction(async (em) => {
|
||||||
const dataStore = em.create(DataStore, { name, columns, projectId });
|
const dataStore = em.create(DataTable, { name, columns, projectId });
|
||||||
await em.insert(DataStore, dataStore);
|
await em.insert(DataTable, dataStore);
|
||||||
dataStoreId = dataStore.id;
|
dataTableId = dataStore.id;
|
||||||
|
|
||||||
const queryRunner = em.queryRunner;
|
const queryRunner = em.queryRunner;
|
||||||
if (!queryRunner) {
|
if (!queryRunner) {
|
||||||
@@ -38,8 +38,8 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
|
|
||||||
// insert columns
|
// insert columns
|
||||||
const columnEntities = columns.map((col, index) =>
|
const columnEntities = columns.map((col, index) =>
|
||||||
em.create(DataStoreColumn, {
|
em.create(DataTableColumn, {
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
name: col.name,
|
name: col.name,
|
||||||
type: col.type,
|
type: col.type,
|
||||||
index: col.index ?? index,
|
index: col.index ?? index,
|
||||||
@@ -47,23 +47,23 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (columnEntities.length > 0) {
|
if (columnEntities.length > 0) {
|
||||||
await em.insert(DataStoreColumn, columnEntities);
|
await em.insert(DataTableColumn, columnEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create user table (will create empty table with just id column if no columns)
|
// create user table (will create empty table with just id column if no columns)
|
||||||
await this.dataStoreRowsRepository.createTableWithColumns(
|
await this.dataStoreRowsRepository.createTableWithColumns(
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
columnEntities,
|
columnEntities,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!dataStoreId) {
|
if (!dataTableId) {
|
||||||
throw new UnexpectedError('Data store creation failed');
|
throw new UnexpectedError('Data store creation failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
const createdDataStore = await this.findOneOrFail({
|
const createdDataStore = await this.findOneOrFail({
|
||||||
where: { id: dataStoreId },
|
where: { id: dataTableId },
|
||||||
relations: ['project', 'columns'],
|
relations: ['project', 'columns'],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
throw new UnexpectedError('QueryRunner is not available');
|
throw new UnexpectedError('QueryRunner is not available');
|
||||||
}
|
}
|
||||||
|
|
||||||
await em.delete(DataStore, { id: dataStoreId });
|
await em.delete(DataTable, { id: dataStoreId });
|
||||||
await this.dataStoreRowsRepository.dropTable(dataStoreId, queryRunner);
|
await this.dataStoreRowsRepository.dropTable(dataStoreId, queryRunner);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -87,7 +87,7 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
|
|
||||||
async deleteDataStoreByProjectId(projectId: string) {
|
async deleteDataStoreByProjectId(projectId: string) {
|
||||||
return await this.manager.transaction(async (em) => {
|
return await this.manager.transaction(async (em) => {
|
||||||
const existingTables = await em.findBy(DataStore, { projectId });
|
const existingTables = await em.findBy(DataTable, { projectId });
|
||||||
|
|
||||||
let changed = false;
|
let changed = false;
|
||||||
for (const match of existingTables) {
|
for (const match of existingTables) {
|
||||||
@@ -106,11 +106,11 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
throw new UnexpectedError('QueryRunner is not available');
|
throw new UnexpectedError('QueryRunner is not available');
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingTables = await em.findBy(DataStore, {});
|
const existingTables = await em.findBy(DataTable, {});
|
||||||
|
|
||||||
let changed = false;
|
let changed = false;
|
||||||
for (const match of existingTables) {
|
for (const match of existingTables) {
|
||||||
const result = await em.delete(DataStore, { id: match.id });
|
const result = await em.delete(DataTable, { id: match.id });
|
||||||
await this.dataStoreRowsRepository.dropTable(match.id, queryRunner);
|
await this.dataStoreRowsRepository.dropTable(match.id, queryRunner);
|
||||||
changed = changed || (result.affected ?? 0) > 0;
|
changed = changed || (result.affected ?? 0) > 0;
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
return await query.getMany();
|
return await query.getMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getManyQuery(options: Partial<ListDataStoreQueryDto>): SelectQueryBuilder<DataStore> {
|
private getManyQuery(options: Partial<ListDataStoreQueryDto>): SelectQueryBuilder<DataTable> {
|
||||||
const query = this.createQueryBuilder('dataStore');
|
const query = this.createQueryBuilder('dataStore');
|
||||||
|
|
||||||
this.applySelections(query);
|
this.applySelections(query);
|
||||||
@@ -141,12 +141,12 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
private applySelections(query: SelectQueryBuilder<DataStore>): void {
|
private applySelections(query: SelectQueryBuilder<DataTable>): void {
|
||||||
this.applyDefaultSelect(query);
|
this.applyDefaultSelect(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
private applyFilters(
|
private applyFilters(
|
||||||
query: SelectQueryBuilder<DataStore>,
|
query: SelectQueryBuilder<DataTable>,
|
||||||
filter: Partial<ListDataStoreQueryDto>['filter'],
|
filter: Partial<ListDataStoreQueryDto>['filter'],
|
||||||
): void {
|
): void {
|
||||||
for (const x of ['id', 'projectId'] as const) {
|
for (const x of ['id', 'projectId'] as const) {
|
||||||
@@ -172,7 +172,7 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private applySorting(query: SelectQueryBuilder<DataStore>, sortBy?: string): void {
|
private applySorting(query: SelectQueryBuilder<DataTable>, sortBy?: string): void {
|
||||||
if (!sortBy) {
|
if (!sortBy) {
|
||||||
query.orderBy('dataStore.updatedAt', 'DESC');
|
query.orderBy('dataStore.updatedAt', 'DESC');
|
||||||
return;
|
return;
|
||||||
@@ -188,7 +188,7 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private applySortingByField(
|
private applySortingByField(
|
||||||
query: SelectQueryBuilder<DataStore>,
|
query: SelectQueryBuilder<DataTable>,
|
||||||
field: string,
|
field: string,
|
||||||
direction: 'DESC' | 'ASC',
|
direction: 'DESC' | 'ASC',
|
||||||
): void {
|
): void {
|
||||||
@@ -202,7 +202,7 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private applyPagination(
|
private applyPagination(
|
||||||
query: SelectQueryBuilder<DataStore>,
|
query: SelectQueryBuilder<DataTable>,
|
||||||
options: Partial<ListDataStoreQueryDto>,
|
options: Partial<ListDataStoreQueryDto>,
|
||||||
): void {
|
): void {
|
||||||
query.skip(options.skip ?? 0);
|
query.skip(options.skip ?? 0);
|
||||||
@@ -211,7 +211,7 @@ export class DataStoreRepository extends Repository<DataStore> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private applyDefaultSelect(query: SelectQueryBuilder<DataStore>): void {
|
private applyDefaultSelect(query: SelectQueryBuilder<DataTable>): void {
|
||||||
query
|
query
|
||||||
.leftJoinAndSelect('dataStore.project', 'project')
|
.leftJoinAndSelect('dataStore.project', 'project')
|
||||||
.leftJoinAndSelect('dataStore.columns', 'data_store_column')
|
.leftJoinAndSelect('dataStore.columns', 'data_store_column')
|
||||||
|
|||||||
@@ -311,14 +311,14 @@ export class DataStoreService {
|
|||||||
return existingTable;
|
return existingTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async validateColumnExists(dataStoreId: string, columnId: string) {
|
private async validateColumnExists(dataTableId: string, columnId: string) {
|
||||||
const existingColumn = await this.dataStoreColumnRepository.findOneBy({
|
const existingColumn = await this.dataStoreColumnRepository.findOneBy({
|
||||||
id: columnId,
|
id: columnId,
|
||||||
dataStoreId,
|
dataTableId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existingColumn === null) {
|
if (existingColumn === null) {
|
||||||
throw new DataStoreColumnNotFoundError(dataStoreId, columnId);
|
throw new DataStoreColumnNotFoundError(dataTableId, columnId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return existingColumn;
|
return existingColumn;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export type DataStoreUserTableName = `${string}data_store_user_${string}`;
|
export type DataStoreUserTableName = `${string}data_table_user_${string}`;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { WithTimestampsAndStringId } from '@n8n/db';
|
import { WithTimestampsAndStringId } from '@n8n/db';
|
||||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from '@n8n/typeorm';
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from '@n8n/typeorm';
|
||||||
|
|
||||||
import { type DataStore } from './data-store.entity';
|
import { type DataTable } from './data-table.entity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Index(['dataStoreId', 'name'], { unique: true })
|
@Index(['dataTableId', 'name'], { unique: true })
|
||||||
export class DataStoreColumn extends WithTimestampsAndStringId {
|
export class DataTableColumn extends WithTimestampsAndStringId {
|
||||||
@Column()
|
@Column()
|
||||||
dataStoreId: string;
|
dataTableId: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
name: string;
|
name: string;
|
||||||
@@ -18,7 +18,7 @@ export class DataStoreColumn extends WithTimestampsAndStringId {
|
|||||||
@Column({ type: 'int' })
|
@Column({ type: 'int' })
|
||||||
index: number;
|
index: number;
|
||||||
|
|
||||||
@ManyToOne('DataStore', 'columns')
|
@ManyToOne('DataTable', 'columns')
|
||||||
@JoinColumn({ name: 'dataStoreId' })
|
@JoinColumn({ name: 'dataTableId' })
|
||||||
dataStore: DataStore;
|
dataTable: DataTable;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Project, WithTimestampsAndStringId } from '@n8n/db';
|
import { Project, WithTimestampsAndStringId } from '@n8n/db';
|
||||||
import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from '@n8n/typeorm';
|
import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from '@n8n/typeorm';
|
||||||
|
|
||||||
import { DataStoreColumn } from './data-store-column.entity';
|
import { DataTableColumn } from './data-table-column.entity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@Index(['name', 'projectId'], { unique: true })
|
@Index(['name', 'projectId'], { unique: true })
|
||||||
export class DataStore extends WithTimestampsAndStringId {
|
export class DataTable extends WithTimestampsAndStringId {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -14,13 +14,13 @@ export class DataStore extends WithTimestampsAndStringId {
|
|||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@OneToMany(
|
@OneToMany(
|
||||||
() => DataStoreColumn,
|
() => DataTableColumn,
|
||||||
(dataStoreColumn) => dataStoreColumn.dataStore,
|
(dataTableColumn) => dataTableColumn.dataTable,
|
||||||
{
|
{
|
||||||
cascade: true,
|
cascade: true,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
columns: DataStoreColumn[];
|
columns: DataTableColumn[];
|
||||||
|
|
||||||
@ManyToOne(() => Project)
|
@ManyToOne(() => Project)
|
||||||
@JoinColumn({ name: 'projectId' })
|
@JoinColumn({ name: 'projectId' })
|
||||||
@@ -28,7 +28,4 @@ export class DataStore extends WithTimestampsAndStringId {
|
|||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
projectId: string;
|
projectId: string;
|
||||||
|
|
||||||
@Column({ type: 'int', default: 0 })
|
|
||||||
sizeBytes: number;
|
|
||||||
}
|
}
|
||||||
@@ -35,9 +35,9 @@ export class DataStoreModule implements ModuleInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async entities() {
|
async entities() {
|
||||||
const { DataStore } = await import('./data-store.entity');
|
const { DataTable } = await import('./data-table.entity');
|
||||||
const { DataStoreColumn } = await import('./data-store-column.entity');
|
const { DataTableColumn } = await import('./data-table-column.entity');
|
||||||
|
|
||||||
return [DataStore, DataStoreColumn] as unknown as Array<new () => BaseEntity>;
|
return [DataTable, DataTableColumn] as unknown as Array<new () => BaseEntity>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import {
|
import { DATA_STORE_COLUMN_REGEX, type DataStoreCreateColumnSchema } from '@n8n/api-types';
|
||||||
DATA_STORE_COLUMN_REGEX,
|
|
||||||
type DataStoreCreateColumnSchema,
|
|
||||||
type DataStoreColumn,
|
|
||||||
} from '@n8n/api-types';
|
|
||||||
import { DslColumn } from '@n8n/db';
|
import { DslColumn } from '@n8n/db';
|
||||||
import type { DataSourceOptions } from '@n8n/typeorm';
|
import type { DataSourceOptions } from '@n8n/typeorm';
|
||||||
import type {
|
import type {
|
||||||
@@ -14,6 +10,7 @@ import type {
|
|||||||
import { UnexpectedError } from 'n8n-workflow';
|
import { UnexpectedError } from 'n8n-workflow';
|
||||||
|
|
||||||
import type { DataStoreUserTableName } from '../data-store.types';
|
import type { DataStoreUserTableName } from '../data-store.types';
|
||||||
|
import type { DataTableColumn } from '../data-table-column.entity';
|
||||||
|
|
||||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||||
|
|
||||||
@@ -213,7 +210,7 @@ export function extractInsertedIds(raw: unknown, dbType: DataSourceOptions['type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizeRows(rows: DataStoreRowsReturn, columns: DataStoreColumn[]) {
|
export function normalizeRows(rows: DataStoreRowsReturn, columns: DataTableColumn[]) {
|
||||||
// we need to normalize system dates as well
|
// we need to normalize system dates as well
|
||||||
const systemColumns = [
|
const systemColumns = [
|
||||||
{ name: 'createdAt', type: 'date' },
|
{ name: 'createdAt', type: 'date' },
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export type DataStoreColumn = {
|
|||||||
name: string;
|
name: string;
|
||||||
type: DataStoreColumnType;
|
type: DataStoreColumnType;
|
||||||
index: number;
|
index: number;
|
||||||
dataStoreId: string;
|
dataTableId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DataStore = {
|
export type DataStore = {
|
||||||
@@ -15,7 +15,6 @@ export type DataStore = {
|
|||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
sizeBytes: number;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CreateDataStoreColumnOptions = Pick<DataStoreColumn, 'name' | 'type'> &
|
export type CreateDataStoreColumnOptions = Pick<DataStoreColumn, 'name' | 'type'> &
|
||||||
|
|||||||
Reference in New Issue
Block a user