PG Plugin Interface
A Package allow to define Go Structs that can execute Code and Register it globally. The Registered Code was named Dispatcher and can be executed over the HandleDispatch Method.
This was use to Communicate between two Worlds for example Postgres and Go.
Example Postgres Plugin
Replace the {ExtensionName} with the name of your extension
main.go
package main
// use the right postgresql code for your postgres version
// #cgo CFLAGS: -I /usr/include/postgresql/11/server/
// #cgo LDFLAGS: -Wl,-unresolved-symbols=ignore-all
/*
extern char* HandleDispatch(char*,char*);
#include "postgres.h"
#include "fmgr.h"
#include "utils/builtins.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(dispatch);
Datum
dispatch(PG_FUNCTION_ARGS)
{
char* name = text_to_cstring(PG_GETARG_TEXT_PP(0));
char* args = text_to_cstring(PG_GETARG_TEXT_PP(1));
char* res = HandleDispatch(name, args);
PG_RETURN_TEXT_P(cstring_to_text(res));
pfree(name);
pfree(args);
pfree(res);
}
*/
import "C"
import (
"gitlab.com/mmorgenstern/{ExtensionName}/cmd/handler"
)
// register the Dispatchers
var _ = handler.Register()
func main() {}
handler/dispatch.go
package handler
import "C"
import (
"gitlab.com/mmorgenstern/{ExtensionName}/dispatcher"
"gitlab.com/mmorgenstern/pg_plugin_interface"
)
// register here all Dispatcher Structs
func Register() int {
pg_plugin_interface.Register(func() pg_plugin_interface.DispatchHandler {
return &dispatcher.TestDispatcher{}
})
return 0
}
//export HandleDispatch
func HandleDispatch(name *C.char, args *C.char) *C.char {
// convert from C String to Go String and vice versa
return C.CString(pg_plugin_interface.HandleDispatch([]string{
C.GoString(name), C.GoString(args),
}))
}
{ExtensionName}--1.0.0.sql (the SQL for the Postgres Plugin)
\echo Use "CREATE EXTENSION {ExtensionName}" to load this file. \quit
CREATE FUNCTION dispatch(text, text) RETURNS text
AS '$libdir/{ExtensionName}', 'dispatch'
LANGUAGE C IMMUTABLE STRICT;
COMMENT ON FUNCTION dispatch(text, text) IS 'dispatch a action with name and arguments to the underlying Go API';
{ExtensionName}.control (the Postgres Plugin Meta Data File)
# extension
comment = ''
default_version = '1.0.0'
relocatable = false
schema = schemaname
Installation
build the Library
export GOOS=linux
export GOARCH=amd64
export CGO_ENABLED=1
export CC=gcc
go mod tidy
go build -o ./{ExtensionName}.so -buildmode=c-shared ./main.go
install in Postgres Instance
cp ./{ExtensionName}.so /usr/lib/postgresql/11/lib
cp ./{ExtensionName}--1.0.0.sql /usr/share/postgresql/11/extension/
cp ./{ExtensionName}.control /usr/share/postgresql/11/extension/
drop extension {ExtensionName};
create extension {ExtensionName};