Skip to content

Instantly share code, notes, and snippets.

@Laeeth

Laeeth/Helper.dpp Secret

Created Sep 7, 2020
Embed
What would you like to do?
module symmetry.integration.fdw.helper;
import std.exception: Exception;
import std.experimental.logger;
public import std.experimental.allocator;
public import symmetry.integration.fdw.pallocator;
#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"
T[n] s(T, size_t n)(auto ref T[n] array) pure nothrow @nogc @safe
{
return array;
}
alias pallocator = Pallocator.instance;
//PG_MODULE_MAGIC;
const(Pg_magic_)* Pg_magic_func()
{
static const(Pg_magic) Pg_magic_data = [
Pg_magic_struct.sizeof,
100005 / 100,
100,
32,
64,
true,
true
].s;
return &Pg_magic_data;
}
// extern int no_such_variable;
//PG_FUNCTION_INFO_V1(git_fdw_handler);
extern Datum git_fdw_handler(FunctionCallInfo fcinfo);
const (Pg_finfo_record)* pg_finfo_git_fdw_handler()
{
static const(Pg_finfo_record) my_finfo = [ 1 ];
return &my_finfo;
}
//PG_FUNCTION_INFO_V1(git_fdw_validator);
extern Datum git_fdw_validator(FunctionCallInfo fcinfo);
extern const(Pg_finfo_record) * pg_finfo_git_fdw_validator();
const(Pg_finfo_record)* pg_finfo_git_fdw_validator()
{
static const(Pg_finfo_record) my_finfo = [ 1 ];
return &my_finfo;
}
struct String
{
char[] data = null;
alias data this;
this(string s)
{
data = makeArray!char(s.length,pallocator);
data[0..s.length] = s[0..s.length];
}
~this()
{
if (data !is null)
{
pallocator.dispose(data);
data = null;
}
}
this(char* s)
{
auto len = strlen(s);
data = makeArray!char(len,pallocator);
foreach(i;0..len)
data[i] = s[i];
}
}
Datum asDatum(ref String s)
{
return cast(Datum)(cast(char*) pstrdup(s.data.ptr));
}
T getPostgresArgument(T)(int argNum)
{
static if (is(T==long))
return PG_GETARG_INT64(argNum);
else static if (is(T==int))
return PG_GETARG_INT32(argNum);
else static if (is(T==uint))
return PG_GETARG_UINT32(argNum);
else static if (is(T==short))
return PG_GETARG_INT16(argNum);
else static if (is(T==ushort))
return PG_GETARG_UINT16(argNum);
else static if (is(T==char))
return PG_GETARG_CHAR(argNum);
else static if (is(T==bool))
return PG_GETARG_BOOL(argNum);
else static if (is(T==Oid))
return PG_GETARG_OID(argNum);
else static if (is(T==String))
return String(PG_GETARG_CSTRING(argNum));
else static if (is(T==float))
return PG_GETARG_FLOAT4(argNum);
else static if (is(T==double))
return PG_GETARG_FLOAT8(argNum);
else static if (is(T==Datum))
return PG_GETARG_DATUM(argNum);
else static assert("unknown pg argument type: " ~ T.stringof);
assert(0);
}
/+
PG_GETARG_DATUM(n))
(PG_GETARG_POINTER(argNum));
#define PG_GETARG_NAME(n) DatumGetName(PG_GETARG_DATUM(n))
/* these macros hide the pass-by-reference-ness of the datatype: */
#define PG_GETARG_DATUM(n) (fcinfo->arg[n])
/* use this if you want the raw, possibly-toasted input datum: */
#define PG_GETARG_RAW_VARLENA_P(n) ((struct varlena *) PG_GETARG_POINTER(n))
/* use this if you want the input datum de-toasted: */
#define PG_GETARG_VARLENA_P(n) PG_DETOAST_DATUM(PG_GETARG_DATUM(n))
/* and this if you can handle 1-byte-header datums: */
#define PG_GETARG_VARLENA_PP(n) PG_DETOAST_DATUM_PACKED(PG_GETARG_DATUM(n))
+/
enum POSTGRESO_UNIX_EPOCH_DAYS = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE);
enum POSTGRESO_UNIX_EPOCH_USECS = (POSTGRESO_UNIX_EPOCH_DAYS * USECS_PER_DAY);
T listCellAs(T)(ListCell* cell)
{
static if (is(isPointer!T))
return cast(T*) cell.data.ptrValue;
else static if (is(T==int))
return cast(T) cell.data.intValue;
else static if (is(T==uint) || is(T==Oid))
return cast(T) cell.data.oidValue;
else static assert("unknown listCell type: "~ T.stringof);
}
struct ListRange(T)
{
List* list = NIL;
ListCell* head;
ListCell* tail;
this(List* list)
{
this.list = list;
this.head = list.head;
this.tail = list.tail;
}
auto length()
{
return list.length;
}
auto front()
{
return listCellAs!T(head.data);
}
auto back()
{
return listCellAs!T(tail.data);
}
void popFront()
{
enforce(head !is null);
head = list.next;
}
void popBack()
{
enforce(tail !is null);
tail = tail.next;
}
bool empty()
{
return (head is null || tail is null);
}
T opIndex(size_t i)
{
return list_nth_cell(list,n.to!int).listCellAs!T;
}
ListRange!T concat(ListRange!T list2)
{
auto newList = list_concat(list,list2);
return ListRange!T(newList);
}
void length(size_t len)
{
if (len < this.length)
{
this.list = list_truncate(this.list,len.to!int);
this.head = list.head;
this.tail = list.tail;
}
else if(len == this.length)
return;
else
{
foreach(i;len - this.length)
list = list_append_unique(list,null);
this.head = list.head;
this.tail = list.tail;
}
}
}
struct PList
{
List* data = NIL;
this(string s)
{
put(s);;
}
void put(string s)
{
data = lappend(data,pstrdup(PString(s).data));
}
}
auto createPString()
{
return PString.init;
}
struct PString
{
StringInfoData* stringInfo = null;
void* data()
{
return stringInfo.data;
}
this(string s)
{
put(s);
}
~this()
{
if (stringInfo !is null)
pfree(stringInfo.data);
}
void put(string s)
{
if(stringInfo is null)
stringInfo = makeStringInfo();
auto temp = makeArray!char(s.length + 1,pallocator);
scope(exit)
pallocator.dispose(temp);
temp = s;
temp.length += 1;
temp[$-1] = '\0';
stringInfo.put(temp.ptr);
}
}
auto make_node(T)
{
/+ Node* _result = cast(Node *) ( ( (T.sizeof & (long.sizeof - 1L)) == 0 && T.sizeof <= 1024)
? MemoryContextAllocZeroAligned(CurrentMemoryContext, (FdwRoutine).sizeof) :
MemoryContextAllocZero(CurrentMemoryContext, (FdwRoutine).sizeof) );
_result.type = (T_FdwRoutine);
return cast(T*) _result; +/
T* _result;
return _result;
}
void put(ref StringInfo stringInfo, string s)
{
appendStringInfo(&stringInfo,s.toStringz);
}
struct DefElemD
{
NodeTag type;
string namespace;
string name;
Node* arg;
DefElemAction action;
int location;
this(DefElem* elem)
{
this.type = elem.type;
this.namespace = elem.namespace.fromStringz;
this.name = elem.defname.fromStringz;
this.arg = elem.arg;
this.action = elem.defaction;
this.location = eleem.location;
}
this(ListCell* cell)
{
this(cast(DefElem*) lfirst(cell));
}
auto toString()
{
return defGetString(&this).fromStringz;
}
}
/**
* This is an opaque structure which is allocated by `git_diff_get_stats`.
* You are responsible for releasing the object memory when done, using the
* `git_diff_stats_free()` function.
*/
struct git_diff_stats;
struct GitDiffStats
{
git_diff_stats* cHandle;
alias handle this;
this(git_diff_stats* handle)
{
this.cHandle = handle;
}
~this()
{
if(this.cHandle !is null)
{
git_diff_stats_free(this.cHandle);
this.cHandle = null;
}
}
}
/**
* Formatting options for diff stats
*/
enum DiffStatsFormat
{
/** No stats*/
none = 0,
/** Full statistics, equivalent of `--stat` */
full = (1u << 0),
/** Short statistics, equivalent of `--shortstat` */
short_ = (1u << 1),
/** Number statistics, equivalent of `--numstat` */
number = (1u << 2),
/** Extended header information such as creations, renames and mode changes, equivalent of `--summary` */
includeSummary = (1u << 3),
}
/**
* Accumulate diff statistics for all patches.
*
* @param out Structure containg the diff statistics.
* @param diff A git_diff generated by one of the above functions.
* @return 0 on success; non-zero on error
*/
int git_diff_get_stats( git_diff_stats **out, git_diff *diff);
/**
* Get the total number of files changed in a diff
*
* @param stats A `git_diff_stats` generated by one of the above functions.
* @return total number of files changed in the diff
*/
size_t git_diff_stats_files_changed(const(git_diff_stats) *stats);
/**
* Get the total number of insertions in a diff
*
* @param stats A `git_diff_stats` generated by one of the above functions.
* @return total number of insertions in the diff
*/
size_t git_diff_stats_insertions(const(git_diff_stats) *stats);
/**
* Get the total number of deletions in a diff
*
* @param stats A `git_diff_stats` generated by one of the above functions.
* @return total number of deletions in the diff
*/
size_t git_diff_stats_deletions(const(git_diff_stats) *stats);
/**
* Print diff statistics to a `git_buf`.
*
* @param out buffer to store the formatted diff statistics in.
* @param stats A `git_diff_stats` generated by one of the above functions.
* @param format Formatting option.
* @param width Target width for output (only affects GIT_DIFF_STATS_FULL)
* @return 0 on success; non-zero on error
*/
int git_diff_stats_to_buf( git_buf *out, const git_diff_stats *stats, GitDiffStatsFormat format, size_t width);
/**
* Deallocate a `git_diff_stats`.
*
* @param stats The previously created statistics object;
* cannot be used after free.
*/
void git_diff_stats_free(git_diff_stats* stats);
size_t filesChanged(GitDiffStats stats)
{
return git_diff_stats_files_changes(stats.cHandle);
}
size_t insertions(GitDiffStats stats)
{
return git_diff_stats_insertions(stats.cHandle);
}
size_t deletions(GitDiffStats stats)
{
return git_diff_stats_deletions(stats.cHandle);
}
string toString(GitDiffStats stats, FormatType formatType, size_t width)
{
git_diff_stats_to_buf(outBuf,stats.cHandle,formatType,width);
}
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.