Skip to content

Commit bdeb68b

Browse files
thomtrpWeiko
authored andcommitted
Add sorter for distant tables (#5546)
As title
1 parent 1cd6612 commit bdeb68b

File tree

7 files changed

+147
-73
lines changed

7 files changed

+147
-73
lines changed

packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/distant-table/distant-table.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from 'src/engine/metadata-modules/remote-server/remote-server.entity';
1111
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
1212
import { DistantTables } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/types/distant-table';
13-
import { STRIPE_DISTANT_TABLES } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/util/stripe-distant-tables.util';
13+
import { STRIPE_DISTANT_TABLES } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/utils/stripe-distant-tables.util';
1414
import { PostgresTableSchemaColumn } from 'src/engine/metadata-modules/remote-server/types/postgres-table-schema-column';
1515

1616
@Injectable()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { RemoteTableStatus } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
2+
import { sortDistantTables } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/utils/sort-distant-tables.util';
3+
4+
const table1 = {
5+
status: RemoteTableStatus.SYNCED,
6+
name: 'table1',
7+
};
8+
9+
const table2 = {
10+
status: RemoteTableStatus.NOT_SYNCED,
11+
name: 'table2',
12+
};
13+
14+
describe('sortDistantTables', () => {
15+
it('should return -1 when first param status is SYNCED and second param status is NOT_SYNCED', () => {
16+
const result = sortDistantTables(table1, table2);
17+
18+
expect(result).toBe(-1);
19+
});
20+
21+
it('should return 1 when first param status is NOT_SYNCED and second param status is SYNCED', () => {
22+
const result = sortDistantTables(table2, table1);
23+
24+
expect(result).toBe(1);
25+
});
26+
27+
it('should return -1 when same status and first param name is smaller than second param name', () => {
28+
const result = sortDistantTables(
29+
{ ...table1, status: RemoteTableStatus.NOT_SYNCED },
30+
table2,
31+
);
32+
33+
expect(result).toBe(-1);
34+
});
35+
36+
it('should return 1 when same status and second param name is smaller than first param name', () => {
37+
const result = sortDistantTables(table2, {
38+
...table1,
39+
status: RemoteTableStatus.NOT_SYNCED,
40+
});
41+
42+
expect(result).toBe(1);
43+
});
44+
45+
it('should be case insensitive', () => {
46+
const result = sortDistantTables(
47+
{ ...table1, name: 'table1', status: RemoteTableStatus.NOT_SYNCED },
48+
{ ...table2, name: 'Table2' },
49+
);
50+
51+
expect(result).toBe(-1);
52+
});
53+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { RemoteTableStatus } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
2+
3+
export const sortDistantTables = (
4+
table1: {
5+
status: RemoteTableStatus;
6+
name: string;
7+
},
8+
table2: {
9+
status: RemoteTableStatus;
10+
name: string;
11+
},
12+
) => {
13+
if (
14+
table1.status === RemoteTableStatus.SYNCED &&
15+
table2.status === RemoteTableStatus.NOT_SYNCED
16+
) {
17+
return -1;
18+
}
19+
20+
if (
21+
table1.status === RemoteTableStatus.NOT_SYNCED &&
22+
table2.status === RemoteTableStatus.SYNCED
23+
) {
24+
return 1;
25+
}
26+
27+
return table1.name.toUpperCase() > table2.name.toUpperCase() ? 1 : -1;
28+
};

packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table-schema-update/remote-table-schema-update.service.ts

+2-52
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import { Injectable } from '@nestjs/common';
22

33
import { getForeignTableColumnName as convertToForeignTableColumnName } from 'src/engine/metadata-modules/remote-server/remote-table/foreign-table/utils/get-foreign-table-column-name.util';
44
import { DistantTables } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/types/distant-table';
5-
import {
6-
RemoteTableStatus,
7-
DistantTableUpdate,
8-
} from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
5+
import { DistantTableUpdate } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
96
import { RemoteTableEntity } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table.entity';
107
import { fetchTableColumns } from 'src/engine/metadata-modules/remote-server/remote-table/utils/fetch-table-columns.util';
118
import { PostgresTableSchemaColumn } from 'src/engine/metadata-modules/remote-server/types/postgres-table-schema-column';
@@ -23,53 +20,6 @@ export class RemoteTableSchemaUpdateService {
2320
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
2421
) {}
2522

26-
public async getDistantTablesWithUpdates({
27-
remoteServerSchema,
28-
workspaceId,
29-
remoteTables,
30-
distantTables,
31-
}: {
32-
remoteServerSchema: string;
33-
workspaceId: string;
34-
remoteTables: RemoteTableEntity[];
35-
distantTables: DistantTables;
36-
}) {
37-
const schemaPendingUpdates =
38-
await this.getSchemaUpdatesBetweenForeignAndDistantTables({
39-
workspaceId,
40-
remoteTables,
41-
distantTables,
42-
});
43-
44-
const remoteTablesDistantNames = new Set(
45-
remoteTables.map((remoteTable) => remoteTable.distantTableName),
46-
);
47-
48-
const distantTablesWithUpdates = Object.keys(distantTables).map(
49-
(tableName) => ({
50-
name: tableName,
51-
schema: remoteServerSchema,
52-
status: remoteTablesDistantNames.has(tableName)
53-
? RemoteTableStatus.SYNCED
54-
: RemoteTableStatus.NOT_SYNCED,
55-
schemaPendingUpdates: schemaPendingUpdates[tableName] || [],
56-
}),
57-
);
58-
59-
const deletedTables = Object.entries(schemaPendingUpdates)
60-
.filter(([_tableName, updates]) =>
61-
updates.includes(DistantTableUpdate.TABLE_DELETED),
62-
)
63-
.map(([tableName, updates]) => ({
64-
name: tableName,
65-
schema: remoteServerSchema,
66-
status: RemoteTableStatus.SYNCED,
67-
schemaPendingUpdates: updates,
68-
}));
69-
70-
return [...distantTablesWithUpdates, ...deletedTables];
71-
}
72-
7323
public computeForeignTableColumnsUpdates = (
7424
foreignTableColumns: PostgresTableSchemaColumn[],
7525
distantTableColumns: PostgresTableSchemaColumn[],
@@ -94,7 +44,7 @@ export class RemoteTableSchemaUpdateService {
9444
return [...columnsAddedUpdates, ...columnsDeletedUpdates];
9545
};
9646

97-
private async getSchemaUpdatesBetweenForeignAndDistantTables({
47+
public async getSchemaUpdatesBetweenForeignAndDistantTables({
9848
workspaceId,
9949
remoteTables,
10050
distantTables,

packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.resolver.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class RemoteTableResolver {
1919
@Args('input') input: FindManyRemoteTablesInput,
2020
@AuthWorkspace() { id: workspaceId }: Workspace,
2121
) {
22-
return this.remoteTableService.findDistantTablesWithStatusByServerId(
22+
return this.remoteTableService.findDistantTablesWithStatus(
2323
input.id,
2424
workspaceId,
2525
input.shouldFetchPendingSchemaUpdates,

packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.service.ts

+62-19
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import {
99
RemoteServerType,
1010
RemoteServerEntity,
1111
} from 'src/engine/metadata-modules/remote-server/remote-server.entity';
12-
import { RemoteTableStatus } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
12+
import {
13+
DistantTableUpdate,
14+
RemoteTableStatus,
15+
} from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
1316
import {
1417
mapUdtNameToFieldType,
1518
mapUdtNameToFieldSettings,
@@ -31,6 +34,7 @@ import { PostgresTableSchemaColumn } from 'src/engine/metadata-modules/remote-se
3134
import { fetchTableColumns } from 'src/engine/metadata-modules/remote-server/remote-table/utils/fetch-table-columns.util';
3235
import { ForeignTableService } from 'src/engine/metadata-modules/remote-server/remote-table/foreign-table/foreign-table.service';
3336
import { RemoteTableSchemaUpdateService } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-schema-update/remote-table-schema-update.service';
37+
import { sortDistantTables } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/utils/sort-distant-tables.util';
3438

3539
export class RemoteTableService {
3640
private readonly logger = new Logger(RemoteTableService.name);
@@ -52,7 +56,7 @@ export class RemoteTableService {
5256
private readonly remoteTableSchemaUpdateService: RemoteTableSchemaUpdateService,
5357
) {}
5458

55-
public async findDistantTablesWithStatusByServerId(
59+
public async findDistantTablesWithStatus(
5660
id: string,
5761
workspaceId: string,
5862
shouldFetchPendingSchemaUpdates?: boolean,
@@ -82,26 +86,37 @@ export class RemoteTableService {
8286
workspaceId,
8387
);
8488

85-
if (currentRemoteTables.length === 0 || !shouldFetchPendingSchemaUpdates) {
86-
const distantTablesWithStatus = Object.keys(distantTables).map(
87-
(tableName) => ({
88-
name: tableName,
89-
schema: remoteServer.schema,
90-
status: currentRemoteTableDistantNames.includes(tableName)
91-
? RemoteTableStatus.SYNCED
92-
: RemoteTableStatus.NOT_SYNCED,
93-
}),
94-
);
89+
const distantTablesWithStatus = Object.keys(distantTables).map(
90+
(tableName) => ({
91+
name: tableName,
92+
schema: remoteServer.schema,
93+
status: currentRemoteTableDistantNames.includes(tableName)
94+
? RemoteTableStatus.SYNCED
95+
: RemoteTableStatus.NOT_SYNCED,
96+
}),
97+
);
9598

96-
return distantTablesWithStatus;
99+
if (!shouldFetchPendingSchemaUpdates) {
100+
return distantTablesWithStatus.sort(sortDistantTables);
97101
}
98102

99-
return this.remoteTableSchemaUpdateService.getDistantTablesWithUpdates({
100-
remoteServerSchema: remoteServer.schema,
101-
workspaceId,
102-
remoteTables: currentRemoteTables,
103-
distantTables,
104-
});
103+
const schemaPendingUpdates =
104+
await this.remoteTableSchemaUpdateService.getSchemaUpdatesBetweenForeignAndDistantTables(
105+
{
106+
workspaceId,
107+
remoteTables: currentRemoteTables,
108+
distantTables,
109+
},
110+
);
111+
112+
const distantTablesWithPendingUpdates =
113+
this.getDistantTablesWithPendingUpdates(
114+
schemaPendingUpdates,
115+
distantTablesWithStatus,
116+
remoteServer.schema,
117+
);
118+
119+
return distantTablesWithPendingUpdates.sort(sortDistantTables);
105120
}
106121

107122
public async findRemoteTablesByServerId({
@@ -442,4 +457,32 @@ export class RemoteTableService {
442457
}
443458
}
444459
}
460+
461+
private getDistantTablesWithPendingUpdates(
462+
schemaPendingUpdates: { [tablename: string]: DistantTableUpdate[] },
463+
distantTablesWithStatus: {
464+
name: string;
465+
schema: string;
466+
status: RemoteTableStatus;
467+
}[],
468+
remoteServerSchema: string,
469+
) {
470+
const distantTablesWithUpdates = distantTablesWithStatus.map((table) => ({
471+
...table,
472+
schemaPendingUpdates: schemaPendingUpdates[table.name] || [],
473+
}));
474+
475+
const deletedTables = Object.entries(schemaPendingUpdates)
476+
.filter(([_tableName, updates]) =>
477+
updates.includes(DistantTableUpdate.TABLE_DELETED),
478+
)
479+
.map(([tableName, updates]) => ({
480+
name: tableName,
481+
schema: remoteServerSchema,
482+
status: RemoteTableStatus.SYNCED,
483+
schemaPendingUpdates: updates,
484+
}));
485+
486+
return [...distantTablesWithUpdates, ...deletedTables];
487+
}
445488
}

0 commit comments

Comments
 (0)