mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
[hotfix ]fix: event mapping query race condition (#8258)
* fix: event mapping query race condition * fixes: duplication dq from lds and gds
This commit is contained in:
parent
c20ec780d7
commit
17983ffb04
2 changed files with 266 additions and 243 deletions
|
|
@ -357,8 +357,15 @@ export class AppImportExportService {
|
||||||
appResourceMappings.appDefaultEnvironmentMapping = appDefaultEnvironmentMapping;
|
appResourceMappings.appDefaultEnvironmentMapping = appDefaultEnvironmentMapping;
|
||||||
appResourceMappings.appVersionMapping = appVersionMapping;
|
appResourceMappings.appVersionMapping = appVersionMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* as multiple operations are run within a single transaction using the transaction method provides a convenient way to handle transactions.
|
||||||
|
* The transaction will automatically committed when the function completes without throwing an error.
|
||||||
|
* If an error occurs during the function execution, the transaction will rolled back.
|
||||||
|
*/
|
||||||
|
|
||||||
|
await manager.transaction(async (transactionalEntityManager) => {
|
||||||
appResourceMappings = await this.setupAppVersionAssociations(
|
appResourceMappings = await this.setupAppVersionAssociations(
|
||||||
manager,
|
transactionalEntityManager,
|
||||||
importingAppVersions,
|
importingAppVersions,
|
||||||
user,
|
user,
|
||||||
appResourceMappings,
|
appResourceMappings,
|
||||||
|
|
@ -404,7 +411,7 @@ export class AppImportExportService {
|
||||||
|
|
||||||
const componentLayouts = [];
|
const componentLayouts = [];
|
||||||
|
|
||||||
const newPage = manager.create(Page, {
|
const newPage = transactionalEntityManager.create(Page, {
|
||||||
name: page.name,
|
name: page.name,
|
||||||
handle: page.handle,
|
handle: page.handle,
|
||||||
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
||||||
|
|
@ -412,7 +419,7 @@ export class AppImportExportService {
|
||||||
disabled: page.disabled || false,
|
disabled: page.disabled || false,
|
||||||
hidden: page.hidden || false,
|
hidden: page.hidden || false,
|
||||||
});
|
});
|
||||||
const pageCreated = await manager.save(newPage);
|
const pageCreated = await transactionalEntityManager.save(newPage);
|
||||||
|
|
||||||
appResourceMappings.pagesMapping[pageId] = pageCreated.id;
|
appResourceMappings.pagesMapping[pageId] = pageCreated.id;
|
||||||
|
|
||||||
|
|
@ -420,7 +427,7 @@ export class AppImportExportService {
|
||||||
component.page = pageCreated;
|
component.page = pageCreated;
|
||||||
});
|
});
|
||||||
|
|
||||||
const savedComponents = await manager.save(Component, mappedComponents);
|
const savedComponents = await transactionalEntityManager.save(Component, mappedComponents);
|
||||||
|
|
||||||
for (const componentId in pageComponents) {
|
for (const componentId in pageComponents) {
|
||||||
const componentLayout = pageComponents[componentId]['layouts'];
|
const componentLayout = pageComponents[componentId]['layouts'];
|
||||||
|
|
@ -441,7 +448,7 @@ export class AppImportExportService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await manager.save(Layout, componentLayouts);
|
await transactionalEntityManager.save(Layout, componentLayouts);
|
||||||
|
|
||||||
//Event handlers
|
//Event handlers
|
||||||
|
|
||||||
|
|
@ -456,7 +463,7 @@ export class AppImportExportService {
|
||||||
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
||||||
};
|
};
|
||||||
|
|
||||||
await manager.save(EventHandler, newEvent);
|
await transactionalEntityManager.save(EventHandler, newEvent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,7 +471,7 @@ export class AppImportExportService {
|
||||||
if (eventObj.event?.length === 0) return;
|
if (eventObj.event?.length === 0) return;
|
||||||
|
|
||||||
eventObj.event.forEach(async (event, index) => {
|
eventObj.event.forEach(async (event, index) => {
|
||||||
const newEvent = await manager.create(EventHandler, {
|
const newEvent = transactionalEntityManager.create(EventHandler, {
|
||||||
name: event.eventId,
|
name: event.eventId,
|
||||||
sourceId: appResourceMappings.componentsMapping[eventObj.componentId],
|
sourceId: appResourceMappings.componentsMapping[eventObj.componentId],
|
||||||
target: Target.component,
|
target: Target.component,
|
||||||
|
|
@ -473,7 +480,7 @@ export class AppImportExportService {
|
||||||
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
||||||
});
|
});
|
||||||
|
|
||||||
await manager.save(EventHandler, newEvent);
|
await transactionalEntityManager.save(EventHandler, newEvent);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -515,7 +522,7 @@ export class AppImportExportService {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await manager.save(EventHandler, tableActionAndColumnEvents);
|
await transactionalEntityManager.save(EventHandler, tableActionAndColumnEvents);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -525,7 +532,7 @@ export class AppImportExportService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await manager.update(
|
await transactionalEntityManager.update(
|
||||||
AppVersion,
|
AppVersion,
|
||||||
{ id: appResourceMappings.appVersionMapping[importingAppVersion.id] },
|
{ id: appResourceMappings.appVersionMapping[importingAppVersion.id] },
|
||||||
{
|
{
|
||||||
|
|
@ -533,17 +540,21 @@ export class AppImportExportService {
|
||||||
homePageId: updateHomepageId,
|
homePageId: updateHomepageId,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const appVersionIds = Object.values(appResourceMappings.appVersionMapping);
|
||||||
|
|
||||||
|
for (const appVersionId of appVersionIds) {
|
||||||
await this.updateEventActionsForNewVersionWithNewMappingIds(
|
await this.updateEventActionsForNewVersionWithNewMappingIds(
|
||||||
manager,
|
manager,
|
||||||
appResourceMappings.appVersionMapping[importingAppVersion.id],
|
appVersionId,
|
||||||
appResourceMappings.dataQueryMapping,
|
appResourceMappings.dataQueryMapping,
|
||||||
appResourceMappings.componentsMapping,
|
appResourceMappings.componentsMapping,
|
||||||
appResourceMappings.pagesMapping,
|
appResourceMappings.pagesMapping
|
||||||
isNormalizedAppDefinitionSchema
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await this.setEditingVersionAsLatestVersion(manager, appResourceMappings.appVersionMapping, importingAppVersions);
|
await this.setEditingVersionAsLatestVersion(manager, appResourceMappings.appVersionMapping, importingAppVersions);
|
||||||
|
|
||||||
|
|
@ -741,13 +752,14 @@ export class AppImportExportService {
|
||||||
|
|
||||||
if (componentEvents.length > 0) {
|
if (componentEvents.length > 0) {
|
||||||
componentEvents.forEach(async (componentEvent) => {
|
componentEvents.forEach(async (componentEvent) => {
|
||||||
const newEvent = new EventHandler();
|
const newEvent = await manager.create(EventHandler, {
|
||||||
newEvent.name = componentEvent.name;
|
name: componentEvent.name,
|
||||||
newEvent.sourceId = savedComponent.id;
|
sourceId: savedComponent.id,
|
||||||
newEvent.target = componentEvent.target;
|
target: componentEvent.target,
|
||||||
newEvent.event = componentEvent.event;
|
event: componentEvent.event,
|
||||||
newEvent.index = componentEvent.index;
|
index: componentEvent.index,
|
||||||
newEvent.appVersionId = appResourceMappings.appVersionMapping[importingAppVersion.id];
|
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
||||||
|
});
|
||||||
|
|
||||||
await manager.save(EventHandler, newEvent);
|
await manager.save(EventHandler, newEvent);
|
||||||
});
|
});
|
||||||
|
|
@ -759,14 +771,14 @@ export class AppImportExportService {
|
||||||
|
|
||||||
if (pageEvents.length > 0) {
|
if (pageEvents.length > 0) {
|
||||||
pageEvents.forEach(async (pageEvent) => {
|
pageEvents.forEach(async (pageEvent) => {
|
||||||
const newEvent = {
|
const newEvent = await manager.create(EventHandler, {
|
||||||
name: pageEvent.name,
|
name: pageEvent.name,
|
||||||
sourceId: pageCreated.id,
|
sourceId: pageCreated.id,
|
||||||
target: pageEvent.target,
|
target: pageEvent.target,
|
||||||
event: pageEvent.event,
|
event: pageEvent.event,
|
||||||
index: pageEvent.index,
|
index: pageEvent.index,
|
||||||
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
||||||
};
|
});
|
||||||
|
|
||||||
await manager.save(EventHandler, newEvent);
|
await manager.save(EventHandler, newEvent);
|
||||||
});
|
});
|
||||||
|
|
@ -790,14 +802,14 @@ export class AppImportExportService {
|
||||||
|
|
||||||
if (importingQueryEvents.length > 0) {
|
if (importingQueryEvents.length > 0) {
|
||||||
importingQueryEvents.forEach(async (dataQueryEvent) => {
|
importingQueryEvents.forEach(async (dataQueryEvent) => {
|
||||||
const newEvent = {
|
const newEvent = await manager.create(EventHandler, {
|
||||||
name: dataQueryEvent.name,
|
name: dataQueryEvent.name,
|
||||||
sourceId: mappedNewDataQuery.id,
|
sourceId: mappedNewDataQuery.id,
|
||||||
target: dataQueryEvent.target,
|
target: dataQueryEvent.target,
|
||||||
event: dataQueryEvent.event,
|
event: dataQueryEvent.event,
|
||||||
index: dataQueryEvent.index,
|
index: dataQueryEvent.index,
|
||||||
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
||||||
};
|
});
|
||||||
|
|
||||||
await manager.save(EventHandler, newEvent);
|
await manager.save(EventHandler, newEvent);
|
||||||
});
|
});
|
||||||
|
|
@ -812,14 +824,14 @@ export class AppImportExportService {
|
||||||
|
|
||||||
if (queryEvents.length > 0) {
|
if (queryEvents.length > 0) {
|
||||||
queryEvents.forEach(async (event, index) => {
|
queryEvents.forEach(async (event, index) => {
|
||||||
const newEvent = {
|
const newEvent = await manager.create(EventHandler, {
|
||||||
name: event.eventId,
|
name: event.eventId,
|
||||||
sourceId: mappedNewDataQuery.id,
|
sourceId: mappedNewDataQuery.id,
|
||||||
target: Target.dataQuery,
|
target: Target.dataQuery,
|
||||||
event: event,
|
event: event,
|
||||||
index: queryEvents.index || index,
|
index: event.index ?? index,
|
||||||
appVersionId: mappedNewDataQuery.appVersionId,
|
appVersionId: appResourceMappings.appVersionMapping[importingAppVersion.id],
|
||||||
};
|
});
|
||||||
|
|
||||||
await manager.save(EventHandler, newEvent);
|
await manager.save(EventHandler, newEvent);
|
||||||
});
|
});
|
||||||
|
|
@ -838,18 +850,17 @@ export class AppImportExportService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const appVersionIds = Object.values(appResourceMappings.appVersionMapping);
|
// const appVersionIds = Object.values(appResourceMappings.appVersionMapping);
|
||||||
|
|
||||||
for (const appVersionId of appVersionIds) {
|
// for (const appVersionId of appVersionIds) {
|
||||||
await this.updateEventActionsForNewVersionWithNewMappingIds(
|
// await this.updateEventActionsForNewVersionWithNewMappingIds(
|
||||||
manager,
|
// manager,
|
||||||
appVersionId,
|
// appVersionId,
|
||||||
appResourceMappings.dataQueryMapping,
|
// appResourceMappings.dataQueryMapping,
|
||||||
appResourceMappings.componentsMapping,
|
// appResourceMappings.componentsMapping,
|
||||||
appResourceMappings.pagesMapping,
|
// appResourceMappings.pagesMapping
|
||||||
true
|
// );
|
||||||
);
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
return appResourceMappings;
|
return appResourceMappings;
|
||||||
}
|
}
|
||||||
|
|
@ -1513,29 +1524,35 @@ export class AppImportExportService {
|
||||||
versionId: string,
|
versionId: string,
|
||||||
oldDataQueryToNewMapping: Record<string, unknown>,
|
oldDataQueryToNewMapping: Record<string, unknown>,
|
||||||
oldComponentToNewComponentMapping: Record<string, unknown>,
|
oldComponentToNewComponentMapping: Record<string, unknown>,
|
||||||
oldPageToNewPageMapping: Record<string, unknown>,
|
oldPageToNewPageMapping: Record<string, unknown>
|
||||||
isNormalizedAppDefinitionSchema: boolean
|
|
||||||
) {
|
) {
|
||||||
const allEvents = await manager.find(EventHandler, {
|
const allEvents = await manager
|
||||||
where: { appVersionId: versionId },
|
.createQueryBuilder(EventHandler, 'event')
|
||||||
});
|
.where('event.appVersionId = :versionId', { versionId })
|
||||||
|
.getMany();
|
||||||
|
|
||||||
for (const event of allEvents) {
|
for (const event of allEvents) {
|
||||||
const eventDefinition = event.event;
|
const eventDefinition = event.event;
|
||||||
|
|
||||||
if (isNormalizedAppDefinitionSchema && eventDefinition?.actionId === 'run-query') {
|
if (eventDefinition?.actionId === 'run-query' && oldDataQueryToNewMapping[eventDefinition.queryId]) {
|
||||||
eventDefinition.queryId = oldDataQueryToNewMapping[eventDefinition.queryId];
|
eventDefinition.queryId = oldDataQueryToNewMapping[eventDefinition.queryId];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventDefinition?.actionId === 'control-component') {
|
if (
|
||||||
|
eventDefinition?.actionId === 'control-component' &&
|
||||||
|
oldComponentToNewComponentMapping[eventDefinition.componentId]
|
||||||
|
) {
|
||||||
eventDefinition.componentId = oldComponentToNewComponentMapping[eventDefinition.componentId];
|
eventDefinition.componentId = oldComponentToNewComponentMapping[eventDefinition.componentId];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventDefinition?.actionId === 'switch-page') {
|
if (eventDefinition?.actionId === 'switch-page' && oldPageToNewPageMapping[eventDefinition.pageId]) {
|
||||||
eventDefinition.pageId = oldPageToNewPageMapping[eventDefinition.pageId];
|
eventDefinition.pageId = oldPageToNewPageMapping[eventDefinition.pageId];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventDefinition?.actionId == 'show-modal' || eventDefinition?.actionId === 'close-modal') {
|
if (
|
||||||
|
(eventDefinition?.actionId == 'show-modal' || eventDefinition?.actionId === 'close-modal') &&
|
||||||
|
oldComponentToNewComponentMapping[eventDefinition.modal]
|
||||||
|
) {
|
||||||
eventDefinition.modal = oldComponentToNewComponentMapping[eventDefinition.modal];
|
eventDefinition.modal = oldComponentToNewComponentMapping[eventDefinition.modal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -685,7 +685,6 @@ export class AppsService {
|
||||||
newDataQueries.push(newQuery);
|
newDataQueries.push(newQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (globalQueries?.length > 0) {
|
if (globalQueries?.length > 0) {
|
||||||
for (const globalQuery of globalQueries) {
|
for (const globalQuery of globalQueries) {
|
||||||
|
|
@ -718,13 +717,19 @@ export class AppsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const newQuery of newDataQueries) {
|
for (const newQuery of newDataQueries) {
|
||||||
const newOptions = this.replaceDataQueryOptionsWithNewDataQueryIds(newQuery.options, oldDataQueryToNewMapping);
|
const newOptions = this.replaceDataQueryOptionsWithNewDataQueryIds(
|
||||||
|
newQuery.options,
|
||||||
|
oldDataQueryToNewMapping
|
||||||
|
);
|
||||||
newQuery.options = newOptions;
|
newQuery.options = newOptions;
|
||||||
|
|
||||||
await manager.save(newQuery);
|
await manager.save(newQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
appVersion.definition = this.replaceDataQueryIdWithinDefinitions(appVersion.definition, oldDataQueryToNewMapping);
|
appVersion.definition = this.replaceDataQueryIdWithinDefinitions(
|
||||||
|
appVersion.definition,
|
||||||
|
oldDataQueryToNewMapping
|
||||||
|
);
|
||||||
await manager.save(appVersion);
|
await manager.save(appVersion);
|
||||||
|
|
||||||
for (const appEnvironment of appEnvironments) {
|
for (const appEnvironment of appEnvironments) {
|
||||||
|
|
@ -747,6 +752,7 @@ export class AppsService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return oldDataQueryToNewMapping;
|
return oldDataQueryToNewMapping;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue