Skip to content

Instantly share code, notes, and snippets.

@Laeeth

Laeeth/API.dpp Secret

Created Sep 7, 2020
Embed
What would you like to do?
/+
use with postgres 10
d++ git_fdw.dpp --include-path /usr/include/postgresql/server
pg_config | grep LIBS
-lpgcommon -lpgport -lpthread -lxml2 -lpam -lssl -lcrypto -lgssapi_krb5 -lz -lreadline -lrt -lcrypt -ldl -lm
-lgit2
+/
module symmetry.integration.fdw.api;
import std.exception: Exception;
import std.experimental.logger;
#include "postgres.h"
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <git2.h>
#include "access/htup_details.h"
#include "access/reloptions.h"
#include "access/sysattr.h"
#include "catalog/pg_foreign_table.h"
#include "commands/defrem.h"
#include "commands/explain.h"
#include "commands/vacuum.h"
#include "foreign/fdwapi.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "optimizer/planmain.h"
#include "optimizer/restrictinfo.h"
#include "optimizer/var.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/builtins.h"
#include "utils/timestamp.h"
extern(C)
{
FdwRoutine* gitFdwHandler()
{
auto ret = make!FdwRoutine(pallocator);
with(ret)
{
.GetForeignRelSize = git_get_foreign_rel_size;
.GetForeignPaths = git_get_foreign_paths;
.GetForeignPlan = git_get_foreign_plan;
.BeginForeignScan = git_begin_foreign_scan;
.IterateForeignScan = git_iterate_foreign_scan;
.EndForeignScan = git_end_foreign_scan;
.ExplainForeignScan = git_explain_foreign_scan;
.ReScanForeignScan = git_rescan_foreign_scan;
.AnalyzeForeignTable = git_analyze_foreign_table;
.ImportForeignSchema = git_import_foreign_schema;
}
return ret;
}
}
Datum git_fdw_handler(PG_FUNCTION_ARGS)
{
return PG_RETURN_POINTER(gitFdwHandler());
}
Datum git_fdw_validator(PG_FUNCTION_ARGS)
{
auto optionsList = untransformRelOptions(getPostgresArgument!Datum(0)).ListRange;
auto catalog = getPostgresArgument!Oid(1);
gitFdwValidator(optionsList,catalog);
PG_RETURN_VOID();
}
string[] gitImportForeignSchema(ImportForeignSchemaStmt* stmt, Oid serverOid)
ForeignScan* make_foreign_scan(List* tlist, List* scanClauses, Index scanRelid, List* a1, ForeignPath* bestPath, Plan* outerPlan)
{
ForeignScan* makeForeignScan(List* tlist, List* scanClauses, Index scanRelid, List* a1, ForeignPath* bestPath, Plan* outerPlan)
}
ForeignScan* git_get_foreign_plan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, ForeignPath *best_path, List* tlist, List* scanClauses, Plan *outerPlan)
List* git_import_foreign_schema(ImportForeignSchemaStmt* stmt, Oid serverOid)
{
return PList(gitImportForeignSchema).data;
}
void estimate_costs(PlannerInfo *root, RelOptInfo *baserel, GitFdwPlanState *planState, Cost *startupCost, Cost *totalCost)
{
auto result = estimateCosts(root,baserel,planState);
*startupCost = result.startupCost;
*totalCost = result.totalCost;
}
bool git_analyze_foreign_table(Relation relation)
{
auto result = gitAnalyzeForeignTable(relation);
*func = result[0];
*totalPages = result[1];
return true;
}
module symmetry.integration.fdw.pallocator;
import std.experimental.allocator.common;
struct DppOffsetSize{int offset; int size; }
#include "postgres.h"
#include "utils/palloc.h"
/**
The Postgresql heap allocator. palloc always returns word-aligned memory
Heavily based off std.experimental.allocator.mallocator;
*/
struct Pallocator
{
@system unittest { testAllocator!(() => Pallocator.instance); }
/**
Postgresql allocator methods per the semantics defined above. The
`deallocate` and `reallocate` methods are `@system` because they
may move memory around, leaving dangling pointers in user code. Somewhat
paradoxically, `palloc` is `@safe` but that's only useful to safe
programs that can afford to leak memory allocated.
*/
@trusted @nogc nothrow
void[] allocate(size_t bytes) shared
{
if (!bytes) return null;
auto p = palloc(bytes);
return p ? p[0 .. bytes] : null;
}
/// Ditto
@system @nogc nothrow
bool deallocate(void[] b) shared
{
pfree(b.ptr);
return true;
}
/// Ditto
@system @nogc nothrow
bool reallocate(ref void[] b, size_t s) shared
{
if (!s)
{
deallocate(b);
b = null;
return true;
}
auto p = cast(ubyte*) repalloc(b.ptr, s);
if (!p) return false;
b = p[0 .. s];
return true;
}
@trusted @nogc nothrow
void[] allocateZeroed()(size_t bytes) shared
{
if (!bytes) return null;
auto p = palloc0(bytes);
return p ? p[0 .. bytes] : null;
}
/**
Returns the global instance of this allocator type. The C heap allocator is
thread-safe, therefore all of its methods and `it` itself are
`shared`.
*/
static shared Pallocator instance;
}
///
@nogc @system nothrow unittest
{
auto buffer = Pallocator.instance.allocate(1024 * 1024 * 4);
scope(exit) Pallocator.instance.deallocate(buffer);
//...
}
@nogc @system nothrow unittest
{
@nogc nothrow
static void test(A)()
{
int* p = null;
p = cast(int*) A.instance.allocate(int.sizeof);
scope(exit) () nothrow @nogc { A.instance.deallocate(p[0 .. int.sizeof]); }();
*p = 42;
assert(*p == 42);
}
test!Pallocator();
}
@nogc @system nothrow unittest
{
static void test(A)()
{
import std.experimental.allocator : make;
Object p = null;
p = A.instance.make!Object();
assert(p !is null);
}
test!Pallocator();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.