On Saturday, 13 January 2018 at 05:28:17 UTC, Joe wrote:
Going beyond the connection, there are various other libpq functions that use a similar pattern of values passed using multiple parallel C arrays, e.g.,

   PGresult *PQexecParams(PGconn *conn,
                       const char *command,
                       int nParams,
                       const Oid *paramTypes,
                       const char * const *paramValues,
                       const int *paramLengths,
                       const int *paramFormats,
                       int resultFormat);

Each of the `paramXxxxs' arguments are arrays (Oid is an alias for uint).
[...]

Focusing on the above function, suppose the first two parameter arrays are defined in a C program as:

    Oid paramTypes[] = {23, 25};
    char *paramValues[] = {"1", "abcde"};

which could be expressed in D as:

    Oid [] paramTypes = [23, 25];
    string [] paramValues = ["1", "abcde"];

I know the paramTypes could be passed as null, letting PG deduce the data types but suppose we have some reason to accumulate types, etc., in D slices. I know the paramValues can be manipulated in a manner similar to the one shown in my first post, namely something like this:

   extern(C) char * [2] pvs;
   foreach (i, val; paramValues)
       pvs[i] = cast(char *)toStringz(val);

And then use "cast(const char **)pvs" for the paramValues argument. The only feedback that I received that was explicit to this approach was in response to my initial post, in which Adam D. Ruppe said that what I did was "decent".

So I have two lingering doubts:

1. Is malloc() the only way to allocate the arrays, either of Oid's, int's or char *'s, for passing to the libpq functions? IOW, isn't there a way to take advantage of D's 'new' (and thus the GC)?

2. How to convert a slice of Oid's or int's to an array of pointers suitable by processing by the libpq C function? A technique similar to the previous one seems to work, e.g.,

    extern(C) Oid [2] pts;
    foreach (i, typ; paramTypes)
        pts[i] = typ;

But I'm not sure if it's really working (when I mistakenly had a * in the pts declaration, at one point it also seemed to work).

Reply via email to