()
| 431 | } |
| 432 | |
| 433 | async createAuditTriggers() { |
| 434 | try { |
| 435 | const functionQuery = ` |
| 436 | CREATE OR REPLACE FUNCTION update_updated_at_column() |
| 437 | RETURNS TRIGGER AS $$ |
| 438 | BEGIN |
| 439 | NEW.updated_at = CURRENT_TIMESTAMP; |
| 440 | RETURN NEW; |
| 441 | END; |
| 442 | $$ language 'plpgsql'; |
| 443 | `; |
| 444 | |
| 445 | await this.pool.query(functionQuery); |
| 446 | |
| 447 | const triggers = [ |
| 448 | { name: 'update_guilds_updated_at', table: pgConfig.tables.guilds }, |
| 449 | { name: 'update_users_updated_at', table: pgConfig.tables.users }, |
| 450 | { name: 'update_welcome_configs_updated_at', table: pgConfig.tables.welcome_configs }, |
| 451 | { name: 'update_leveling_configs_updated_at', table: pgConfig.tables.leveling_configs }, |
| 452 | { name: 'update_user_levels_updated_at', table: pgConfig.tables.user_levels }, |
| 453 | { name: 'update_economy_updated_at', table: pgConfig.tables.economy }, |
| 454 | { name: 'update_application_roles_updated_at', table: pgConfig.tables.application_roles }, |
| 455 | { name: 'update_invite_tracking_updated_at', table: pgConfig.tables.invite_tracking }, |
| 456 | { name: 'update_guild_users_updated_at', table: pgConfig.tables.guild_users }, |
| 457 | { name: 'update_birthdays_updated_at', table: pgConfig.tables.birthdays }, |
| 458 | { name: 'update_giveaways_updated_at', table: pgConfig.tables.giveaways }, |
| 459 | { name: 'update_tickets_updated_at', table: pgConfig.tables.tickets }, |
| 460 | { name: 'update_afk_status_updated_at', table: pgConfig.tables.afk_status }, |
| 461 | ]; |
| 462 | |
| 463 | const allowedTriggerIdentifiers = new Set(triggers.map(trigger => trigger.name)); |
| 464 | |
| 465 | for (const trigger of triggers) { |
| 466 | try { |
| 467 | const safeTriggerIdentifier = assertAllowlistedIdentifier( |
| 468 | trigger.name, |
| 469 | allowedTriggerIdentifiers, |
| 470 | 'Trigger identifier' |
| 471 | ); |
| 472 | const safeTableIdentifier = assertAllowlistedIdentifier( |
| 473 | trigger.table, |
| 474 | this.allowedTableIdentifiers, |
| 475 | 'Trigger table identifier' |
| 476 | ); |
| 477 | |
| 478 | await this.pool.query( |
| 479 | `DROP TRIGGER IF EXISTS ${quoteIdentifier(safeTriggerIdentifier)} ON ${quoteIdentifier(safeTableIdentifier)};` |
| 480 | ); |
| 481 | await this.pool.query( |
| 482 | `CREATE TRIGGER ${quoteIdentifier(safeTriggerIdentifier)} |
| 483 | BEFORE UPDATE ON ${quoteIdentifier(safeTableIdentifier)} |
| 484 | FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();` |
| 485 | ); |
| 486 | } catch (error) { |
| 487 | logger.warn(`Error creating trigger ${trigger.name} on ${trigger.table}: ${error.message}`); |
| 488 | } |
| 489 | } |
| 490 |
no test coverage detected