I just realized I completely borked the patch file.

My apologies. Attached a (hopefully) correct patch file.

---
Swen Kooij

On Mon, Sep 2, 2019 at 9:54 PM Swen Kooij <swenko...@gmail.com> wrote:
>
> Hello all,
>
> I've been working on an extension that tightly integrates
> postgres with underlying filesystem . I need to customize
> how postgres copies directories for new databases.
>
> I first looked at the ProcessUtility_hook. This would require
> me to copy or rewrite most of the createdb() function. This is
> less than ideal of course. Someone on the IRC channel
> suggested I could add a hook for copydir().
>
> I implemented the hook similar to how the
> ProcessUtility_hook is implemented. I couldn't find any tests
> for any of the existing hooks. I've been looking at the regression
> tests, but I am not entirely sure how to proceed on that front.
>
> I tested my patch extensively against master and
> the REL_12_STABLE branch. All tests pass and the patch has
> been working great with my extension.
>
> I attached a first draft of the patch against master.
>
> ---
> Swen Kooij
From 7033aed34e3b35859c470a738a5efbe48f101418 Mon Sep 17 00:00:00 2001
From: Swen Kooij <swenko...@gmail.com>
Date: Sun, 1 Sep 2019 22:42:04 +0300
Subject: [PATCH] Add hook for copydir()

Plugins/extensions that want to customize how
PostgreSQL interact with the filesystem can hook
in copydir() instead of having to hook in on
a higher level and potentially copy large amounts
of code.

One example use case is wanting to customize how
directories for new databases are created. Without
this hook, one would have to use ProcessUtility_hook.
This would require copying the vast majority of createdb().
---
 src/backend/storage/file/copydir.c | 19 +++++++++++++++++++
 src/include/storage/copydir.h      |  5 +++++
 2 files changed, 24 insertions(+)

diff --git a/src/backend/storage/file/copydir.c b/src/backend/storage/file/copydir.c
index ca1c9cd765..e44bebf947 100644
--- a/src/backend/storage/file/copydir.c
+++ b/src/backend/storage/file/copydir.c
@@ -27,6 +27,9 @@
 #include "miscadmin.h"
 #include "pgstat.h"
 
+/* Hook for plugins to get control in copydir() */
+copydir_hook_type copydir_hook = NULL;
+
 /*
  * copydir: copy a directory
  *
@@ -36,6 +39,22 @@
 void
 copydir(char *fromdir, char *todir, bool recurse)
 {
+	if (copydir_hook)
+		(*copydir_hook) (fromdir, todir, recurse);
+	else
+		standard_copydir(fromdir, todir, recurse);
+}
+
+/*
+ * copydir: copy a directory
+ *
+ * If recurse is false, subdirectories are ignored.  Anything that's not
+ * a directory or a regular file is ignored.
+ */
+void
+standard_copydir(char *fromdir, char *todir, bool recurse)
+{
+
 	DIR		   *xldir;
 	struct dirent *xlde;
 	char		fromfile[MAXPGPATH * 2];
diff --git a/src/include/storage/copydir.h b/src/include/storage/copydir.h
index 525cc6203e..8b73184177 100644
--- a/src/include/storage/copydir.h
+++ b/src/include/storage/copydir.h
@@ -13,7 +13,12 @@
 #ifndef COPYDIR_H
 #define COPYDIR_H
 
+/* Hook for plugins to get control in copydir() */
+typedef void (*copydir_hook_type) (char *fromdir, char *todir, bool recurse);
+extern PGDLLIMPORT copydir_hook_type copydir_hook;
+
 extern void copydir(char *fromdir, char *todir, bool recurse);
+extern void standard_copydir(char *fromdir, char *todir, bool recurse);
 extern void copy_file(char *fromfile, char *tofile);
 
 #endif							/* COPYDIR_H */
-- 
2.20.1

Reply via email to