Skip to content

Instantly share code, notes, and snippets.

@niquola
Forked from Meekohi/libpq_multirow_insert.cc
Created July 30, 2018 21:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niquola/ed464ca4106e27a3be271ea07af2a7ec to your computer and use it in GitHub Desktop.
Save niquola/ed464ca4106e27a3be271ea07af2a7ec to your computer and use it in GitHub Desktop.
Example of a multi-row insert using libpq
#include <stdio.h>
#include <iostream>
using namespace std;
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
using namespace cv;
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
static void exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int main( int argc, char** argv )
{
// Parse Command Line Arguments
if( argc != 3 ) { cout << argv[0] << " image.jpg pgid" << endl; return -1; }
Mat img = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
if( !img.data ) { cout << "[!] Error reading image " << endl; return -1; }
long pgid = atol(argv[2]);
// Run OpenCV Feature Detector
BRISK detector;
vector<KeyPoint> keypoints;
Mat desc;
Mat mask = Mat::ones(img.cols, img.rows, CV_8U);
detector( img, mask, keypoints, desc, false );
// Connect to Database
const char *conninfo = "Connection URL to your Postgres Instance";
PGconn *conn = PQconnectdb(conninfo);
if (PQstatus(conn) != CONNECTION_OK) {
fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
exit_nicely(conn);
}
int nElem = 6*keypoints.size();
Oid* paramTypes = new Oid[nElem];
char** paramValues = new char*[nElem];
int* paramLengths = new int[nElem];
int* paramFormats = new int[nElem];
char* pgcmd = new char[256+64*keypoints.size()];
strcpy(pgcmd,"INSERT INTO brisk VALUES ");
// Insert features into database
for(int i = 0; i < keypoints.size(); i++) {
const double* feature = desc.ptr<double>(i);
char* i0 = new char[64];
char* i1;
char* i2 = new char[64];
char* i3 = new char[64];
char* i4 = new char[64];
char* i5 = new char[64];
// convert everything to text for postgres, (except for the binary feature)
snprintf(i0,2048,"%ld",pgid);
i1 = (char*)feature;
snprintf(i2,2048,"%f",keypoints[i].pt.x);
snprintf(i3,2048,"%f",keypoints[i].pt.y);
snprintf(i4,2048,"%f",keypoints[i].size);
snprintf(i5,2048,"%f",keypoints[i].angle);
paramTypes[6*i+0] = 0; paramValues[6*i+0] = i0; paramFormats[6*i+0] = 0; paramLengths[6*i+0] = 0;
paramTypes[6*i+1] = 17; paramValues[6*i+1] = i1; paramFormats[6*i+1] = 1; paramLengths[6*i+1] = desc.row(i).cols;
paramTypes[6*i+2] = 0; paramValues[6*i+2] = i2; paramFormats[6*i+2] = 0; paramLengths[6*i+2] = 0;
paramTypes[6*i+3] = 0; paramValues[6*i+3] = i3; paramFormats[6*i+3] = 0; paramLengths[6*i+3] = 0;
paramTypes[6*i+4] = 0; paramValues[6*i+4] = i4; paramFormats[6*i+4] = 0; paramLengths[6*i+4] = 0;
paramTypes[6*i+5] = 0; paramValues[6*i+5] = i5; paramFormats[6*i+5] = 0; paramLengths[6*i+5] = 0;
char chunk[1024];
snprintf(chunk,1024,"($%d,$%d,$%d,$%d,$%d,$%d)",6*i+1,6*i+2,6*i+3,6*i+4,6*i+5,6*i+6);
if(i > 0) strcat(pgcmd,",");
strcat(pgcmd,chunk);
}
// Insert data
PGresult* res = PQexecParams(conn,
pgcmd,
nElem,
paramTypes,
paramValues,
paramLengths,
paramFormats,
0
);
// Check for errors
if ( PQresultStatus(res) != PGRES_COMMAND_OK ) {
fprintf(stderr, "[!] Insert failed!\n%s", PQresultErrorMessage(res));
PQclear(res);
exit_nicely(conn);
} else {
printf("Insert succeeded.\n");
PQclear(res);
}
PQfinish(conn);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment