Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 13x 9x 13x 13x 13x 13x 9x 9x 9x 9x 9x 9x 3x | 'use strict';
const _notifyFunctionSql = (channel: string): string => `
CREATE OR REPLACE FUNCTION owservable_notify() RETURNS trigger AS $$
DECLARE
pk_column text := TG_ARGV[0];
pk_value text;
changed text[];
BEGIN
IF TG_OP = 'DELETE' THEN
pk_value := to_jsonb(OLD) ->> pk_column;
ELSE
pk_value := to_jsonb(NEW) ->> pk_column;
END IF;
IF TG_OP = 'UPDATE' THEN
SELECT array_agg(o.key) INTO changed
FROM jsonb_each(to_jsonb(OLD)) o
JOIN jsonb_each(to_jsonb(NEW)) n ON o.key = n.key
WHERE o.value IS DISTINCT FROM n.value;
END IF;
PERFORM pg_notify(
'${channel}',
json_build_object('table', TG_TABLE_NAME, 'op', lower(TG_OP), 'id', pk_value, 'changed', changed)::text
);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;`;
const _tableTriggerSql = (tableName: string, pkColumn: string): string => `
CREATE OR REPLACE TRIGGER "${tableName}_owservable_notify"
AFTER INSERT OR UPDATE OR DELETE ON "${tableName}"
FOR EACH ROW EXECUTE FUNCTION owservable_notify('${pkColumn}');`;
const installPostgresTriggers = async (orm: any, entities: any[], channel: string = 'owservable'): Promise<void> => {
const connection: any = orm.em.getConnection();
await connection.execute(_notifyFunctionSql(channel));
for (const entity of entities) {
const meta: any = orm.getMetadata().get(entity.name);
const tableName: string = meta.tableName;
const pkProperty: string = meta.primaryKeys[0];
const pkColumn: string = meta.properties[pkProperty]?.fieldNames?.[0] ?? pkProperty;
await connection.execute(_tableTriggerSql(tableName, pkColumn));
console.log(`[@owservable/postgres] -> installPostgresTriggers: live updates enabled for table "${tableName}"`);
}
};
export default installPostgresTriggers;
|