24.06.2022

Trigger, Notify, Listen

 

PostgreSQL Veri Tabanı Yönetim Sistemi (VTYS ya da İngilizce kısaltmasıyla RDBMS) kullanırken bir tabloya yeni kayıt eklendiğinde ya da bir kayıt güncellendiğinde uzaktaki bir kaynağa erişmek, bir API metodu çağırmak gibi işlemler yapmak isterseniz PostgreSQL'in notification sistemini kullanabilirsiniz.

NOTIFY ve LISTEN ile ilgili detaylı bilgiye linklerden ulaşabilirsiniz. Özetle NOTIFY bir notification gönderilmesini, LISTEN ise gönderilen notificationların alınmasını sağlıyor.

Nasıl kullanılacağını örnek bir Javascript uygulaması ile göstermeye çalışacağım ama öncelikle bir veri tabanı ve bir tabloya ihtiyacımız var. Tablonun ne olduğu aslında önemli değil ama aşağıdaki gibi bir tablo oluşturabilirsiniz.

DROP SEQUENCE IF EXISTS "public"."post_id_seq";
CREATE SEQUENCE "public"."post_id_seq" 
INCREMENT 1
MINVALUE  1
MAXVALUE 9223372036854775807
START 1
CACHE 1;

DROP TABLE IF EXISTS "public"."post";
CREATE TABLE "public"."post" (
  "id" int8 NOT NULL DEFAULT nextval('post_id_seq'::regclass),
  "title" varchar(255) COLLATE "pg_catalog"."default",
  "content" text COLLATE "pg_catalog"."default",
  "create_date" date DEFAULT now()
);

ALTER TABLE "public"."post" ADD CONSTRAINT "post_pkey" PRIMARY KEY ("id");

Ayrıca notification'ı gönderecek bir fonksiyona ve bu fonksiyonu istenen INSERT işlemi sonrasında çağıracak olan bir trigger'a ihtiyacımız olacak.

DROP FUNCTION IF EXISTS "public"."notify_new_post"();
CREATE OR REPLACE FUNCTION "public"."notify_new_post"()
  RETURNS "pg_catalog"."trigger" AS $BODY$
begin
  PERFORM pg_notify('new_post_event', row_to_json(NEW)::text);
  RETURN NULL;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

CREATE TRIGGER "notify_new_post_trigger" AFTER INSERT ON "public"."post"
FOR EACH ROW
EXECUTE PROCEDURE "public"."notify_new_post"();

notify_new_post_trigger isimli trigger, post tablosuna yeni bir kayıt insert edildikten sonra notify_new_post fonksiyonunu çağırıyor. Bu fonksiyon pg_notify fonksiyonunu kullanarak yeni bir notification oluşturuyor.

Sıra dinlemeye geldi. Basit bir Javascript kodu yazarak gönderilen notificationları dinleyip insert edilen kayıtları konsola yazalım. Aşağıdaki kodu `index.js` dosyasına kaydedip `npm init -y` ve `npm install pg` komutları ile veri tabanı bağlantısı için gerekli paketi kurabilir, `node .\index.js` komutu ile çalıştırabilirsiniz. Elbette sisteminizde node kurulu olmalı ve config nesnesi içindeki bağlantı bilgilerini de kendinize uygun şekilde değiştirmelisiniz.

const pg = require('pg');

const config = {
    user: 'user',
    password: 'password',
    host: 'localhost',
    db: 'db',
};

const connectionString = `postgres://${config.user}:${config.password}@${config.host}/${config.db}`;

const pgClient = new pg.Client(connectionString);

pgClient.connect();

const query = pgClient.query('LISTEN new_post_event');

pgClient.on('notification', async (data) => {
    const payload = JSON.parse(data.payload);
    console.log('New Post!', payload);
});

yukarıdaki kod çalışır haldeyken post tablosuna yeni bir kayıt eklediğinizdeki aşağıdaki gibi konsola eklenen kaydın bilgilerinin yazıldığını göreceksiniz.









Çok farklı şekillerde kullanılabilir. Örneğin: yeni eklenen kayıt ile ilgili bir Tweet atmak için API'a request gönderebilir,  önceden belirlenmiş kullanıcılara bildirim gönderebilirsiniz.

Esen kalın.