diff --git a/packages/node-core/src/indexer/store.service.ts b/packages/node-core/src/indexer/store.service.ts index 25e844984d..1a47b180e4 100644 --- a/packages/node-core/src/indexer/store.service.ts +++ b/packages/node-core/src/indexer/store.service.ts @@ -34,7 +34,7 @@ import { createUniqueIndexQuery, dropNotifyTrigger, getFkConstraint, - getNotifyTriggers, + getTriggers, SmartTags, smartTags, getVirtualFkTag, @@ -67,6 +67,8 @@ interface NotifyTriggerPayload { triggerName: string; eventManipulation: string; } + +type SchemaTriggerPayload = string; @Injectable() export class StoreService { private tx?: Transaction; @@ -161,6 +163,17 @@ export class StoreService { if (this.config.subscription) { extraQueries.push(createSendNotificationTriggerFunction); } + + /* These SQL queries are to allow hot-schema reload on query service */ + extraQueries.push(createSchemaTriggerFunction(schema)); + const schemaTriggerName = makeTriggerName(schema, '_metadata', 'schema'); + + const schemaTriggers = await getTriggers(this.sequelize, schemaTriggerName); + + if (schemaTriggers.length === 0) { + extraQueries.push(createSchemaTrigger(schema)); + } + for (const model of this.modelsRelations.models) { const attributes = modelsTypeToModelAttributes(model, enumTypeMap); const indexes = model.indexes.map(({fields, unique, using}) => ({ @@ -189,21 +202,15 @@ export class StoreService { extraQueries.push(createExcludeConstraintQuery(schema, sequelizeModel.tableName)); } - /* These SQL queries are to allow hot-schema reload on query service */ - extraQueries.push(createSchemaTriggerFunction(schema)); - extraQueries.push(createSchemaTrigger(schema)); - if (this.config.subscription) { - const triggerName = makeTriggerName(schema, sequelizeModel.tableName); - const triggers = await this.sequelize.query(getNotifyTriggers(), { - replacements: {triggerName}, - type: QueryTypes.SELECT, - }); + const triggerName = makeTriggerName(schema, sequelizeModel.tableName, 'notify'); + const notifyTriggers = await getTriggers(this.sequelize, triggerName); + // Triggers not been found - if (triggers.length === 0) { + if (notifyTriggers.length === 0) { extraQueries.push(createNotifyTrigger(schema, sequelizeModel.tableName)); } else { - this.validateNotifyTriggers(triggerName, triggers as NotifyTriggerPayload[]); + this.validateNotifyTriggers(triggerName, notifyTriggers as NotifyTriggerPayload[]); } } else { extraQueries.push(dropNotifyTrigger(schema, sequelizeModel.tableName)); diff --git a/packages/node-core/src/utils/sync-helper.ts b/packages/node-core/src/utils/sync-helper.ts index 690386663e..eb3b52ce4c 100644 --- a/packages/node-core/src/utils/sync-helper.ts +++ b/packages/node-core/src/utils/sync-helper.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import {blake2AsHex} from '@polkadot/util-crypto'; -import {Utils} from 'sequelize'; +import {QueryTypes, Sequelize, Utils} from 'sequelize'; export interface SmartTags { foreignKey?: string; @@ -122,17 +122,23 @@ END; $$ LANGUAGE plpgsql;`; export function dropNotifyTrigger(schema: string, table: string): string { - const triggerName = makeTriggerName(schema, table); + const triggerName = makeTriggerName(schema, table, 'notify'); return `DROP TRIGGER IF EXISTS "${triggerName}" ON "${schema}"."${table}";`; } -export function getNotifyTriggers(): string { - return `select trigger_name as "triggerName", event_manipulation as "eventManipulation" from information_schema.triggers - WHERE trigger_name = :triggerName`; +export async function getTriggers(sequelize: Sequelize, triggerName: string): Promise { + return sequelize.query( + `select trigger_name as "triggerName", event_manipulation as "eventManipulation" from information_schema.triggers + WHERE trigger_name = :triggerName`, + { + replacements: {triggerName}, + type: QueryTypes.SELECT, + } + ); } export function createNotifyTrigger(schema: string, table: string): string { - const triggerName = makeTriggerName(schema, table); + const triggerName = makeTriggerName(schema, table, 'notify'); return ` CREATE TRIGGER "${triggerName}" AFTER INSERT OR UPDATE OR DELETE @@ -140,14 +146,15 @@ CREATE TRIGGER "${triggerName}" FOR EACH ROW EXECUTE FUNCTION send_notification();`; } -export function makeTriggerName(schema: string, tableName: string): string { +export function makeTriggerName(schema: string, tableName: string, triggerType: string): string { // max name length is 63 bytes in Postgres - return blake2AsHex(`${schema}_${tableName}_notify_trigger`).substr(2, 10); + return blake2AsHex(`${schema}_${tableName}_${triggerType}_trigger`).substr(2, 10); } export function createSchemaTrigger(schema: string): string { + const triggerName = makeTriggerName(schema, '_metadata', 'schema'); return ` - CREATE OR REPLACE TRIGGER "${schema}_metadata_schema_trigger" + CREATE TRIGGER "${triggerName}" AFTER UPDATE ON "${schema}"."_metadata" FOR EACH ROW