Question

I'm doing sql request to a PostgreSQL database using PQexecParams function :

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

To pass paramValues, I use sprintf :

sprintf(buffer1, "%d", stats.packets_count);
values2[0] = buffer1;
sprintf(buffer2, "%d", stats.packets_count_gap);
values2[1] = buffer2;
sprintf(buffer3, "%f", stats.packets_mean);
values2[2] = buffer3;
sprintf(buffer4, "%f", stats.variance);
values2[3] = buffer4;
sprintf(buffer5, "%f", stats.square_mean);
values2[4] = buffer5;
sprintf(buffer6, "%f", stats.standard_deviation);
values2[5] = buffer6;
sprintf(buffer7, "%d", stats.is_ddos);
values2[6] = buffer7;
sprintf(buffer8, "%f", stats.threshold);
values2[7] = buffer8;
sprintf(buffer9, "%d", stats.bandwidth);
values2[8] = buffer9;
values2[9] = proto_name;
sprintf(buffer11, "%f", packet_proto_ratio);
values2[10] = buffer11;
sprintf(buffer12, "%f", tcp_sign_ratio);
values2[11] = buffer12;
sprintf(buffer13, "%d", inflow_outflow_gap);
values2[12] = buffer13;
sprintf(buffer14, "%f", bandwidth_ratio);
values2[13] = buffer14;

And here is the request :

result = PQexecParams(psql, "INSERT INTO statistics (packets_count, packets_count_gap,  mean, variance, square_mean, standard_deviation, is_ddos, date, threshold, bandwidth, protocol, packet_proto_ratio, tcp_sign_ratio, inflow_outflow_gap, bandwidth_ratio) VALUES ($1, $2, $3, $4, $5, $6, $7, now(), $8, $9, $10, $11, $12, $13, $14);", 14, NULL, values2, lengths2, NULL, 0);

But it feel really dirty to do it this way, is there any way to reuse a single buffer pointer ? Because I have several place in my code that need to execute a sql request so i end up with a lot of buffers.

Thanks !

Was it helpful?

Solution

Each buffer points to a separate chunk of memory, with a separate value in it. So no, you cannot reuse them. They must all remain valid and intact until you send them to the PostgreSQL server.

What you can do - if you know how big the total data set will be - is to allocate a single big buffer. Then advance the write pointer by the data length written whenever you append data to it. So all the pointers in the values array point to different, non-overlapping parts of the same client side buffer.

This is quite easy, as sprintf returns the number of characters printed, excluding the null terminator.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top