emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/pq 8151e0bc99 60/63: Add function pq:notifies to suppor


From: ELPA Syncer
Subject: [elpa] externals/pq 8151e0bc99 60/63: Add function pq:notifies to support LISTEN.
Date: Mon, 14 Feb 2022 23:24:28 -0500 (EST)

branch: externals/pq
commit 8151e0bc99e090c570bbe08a686dacfac5f3bbc2
Author: Andreas Seltenreich <seltenreich@gmx.de>
Commit: Andreas Seltenreich <seltenreich@gmx.de>

    Add function pq:notifies to support LISTEN.
---
 pq.c    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 test.el | 22 ++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/pq.c b/pq.c
index ab13da6c00..abf6e0ee63 100644
--- a/pq.c
+++ b/pq.c
@@ -282,6 +282,43 @@ Fpq_reset (emacs_env *env, ptrdiff_t nargs, emacs_value 
args[], void *data)
   return Qt;
 }
 
+static emacs_value
+Fpq_notifies (emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data)
+{
+  PGconn *conn = env->get_user_ptr(env, args[0]);
+
+  if (env->non_local_exit_check (env) != emacs_funcall_exit_return)
+    return NULL;
+
+  if (!connection_ok(env, conn)) {
+    return NULL;
+  }
+
+  PQconsumeInput(conn);
+
+  emacs_value Qvector = env->intern (env, "vector");
+  emacs_value Qcons = env->intern (env, "cons");
+  emacs_value result = Qnil;
+
+  PGnotify *notify;
+  while ((notify = PQnotifies(conn)) != NULL)
+  {
+       emacs_value vector_args[3];
+       vector_args[0] = env->make_string(env, notify->relname, 
strlen(notify->relname));
+       vector_args[1] = env->make_integer(env, notify->be_pid);
+       vector_args[2] = env->make_string(env, notify->extra, 
strlen(notify->extra));
+
+       PQfreemem(notify);
+
+       emacs_value cons_args[2];
+       cons_args[0] = env->funcall (env, Qvector, 3, vector_args);
+       cons_args[1] = result;
+       result = env->funcall (env, Qcons, 2, cons_args);
+  }
+
+  return result;
+}
+
 /* Bind NAME to FUN.  */
 static void
 bind_function (emacs_env *env, const char *name, emacs_value Sfun)
@@ -394,6 +431,13 @@ emacs_module_init (struct emacs_runtime *ert)
        "\n\(fn CONN)",
        NULL);
 
+  DEFUN("pq:notifies", Fpq_notifies, 1, 1,
+       "Get asynchronous notifications recieved on CONN.\n"
+       "\n"
+       "Returns list of vectors [channel-string pid payload-string]\n"
+       "\n\(fn CONN)",
+       NULL);
+
 #undef DEFUN
 
   /* Define custom error signal.  The error data is a list with two
diff --git a/test.el b/test.el
index 68d84a2735..4988725e24 100644
--- a/test.el
+++ b/test.el
@@ -102,3 +102,25 @@
     (with-current-buffer "*Messages*"
       (goto-char (point-max))
       (re-search-backward "ert_nonexisting_table"))))
+
+(ert-deftest pq-async-notify-test ()
+  (let* ((conn (pq:connectdb *conninfo*))
+        (mypid (car (pq:query conn "select pg_backend_pid()"))))
+    (pq:notifies conn)
+    (pq:query conn "listen ert_notification")
+    (pq:query conn "notify ert_notification")
+    (should
+     (equal
+      (car (pq:notifies conn))
+      (vector "ert_notification" mypid "")))
+    (should (equal (pq:notifies conn) nil))
+    (pq:query conn "notify ert_notification, 'paylöad'")
+    (should
+     (equal
+      (car (pq:notifies conn))
+      (vector "ert_notification" mypid "paylöad")))
+    (should-error (pq:notifies 0))
+    (should-error (pq:notifies nil))
+    (should-error (pq:query conn "select pg_terminate_backend($1)" mypid))
+    (should-error (pq:notifies conn))
+))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]