to_pg_array.cpp
text/x-c++src
Filename: to_pg_array.cpp
Type: text/x-c++src
Part: 0
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <pqxx/pqxx>
using namespace std;
using namespace pqxx;
struct true_type
{
};
struct false_type
{
};
template<typename T>
struct is_container:public false_type
{
};
template<typename T, typename U>
struct is_container<vector<T, U> >:public true_type
{
};
template<typename T, typename U>
struct is_container<deque<T, U> >:public true_type
{
};
template<typename T, typename U>
struct is_container<list<T, U> >:public true_type
{
};
template<typename T, typename U, typename V>
struct is_container<set<T, U, V> >:public true_type
{
};
template<typename T>
void do_pg_empty_element(const T&, stringstream&, false_type)
{
// do nothing; there is no element/constant
}
template<typename container>
void do_pg_empty_element(const container& elm, stringstream& append, true_type)
{
typedef typename container::value_type contained_type;
// empty inner array
append << "{";
do_pg_empty_element(contained_type(), append, is_container<contained_type>());
append << "}";
}
// terminating condition: individual elements
template<typename T>
void do_pg_array_element(const T& elm, stringstream& append, false_type)
{
append << "\"" << elm << "\"";
}
// append outer part of nested array
template<typename container>
void do_pg_array_element(const container& cnt, stringstream& append, true_type)
{
typedef typename container::const_iterator it;
typedef typename container::value_type contained_type;
it last = cnt.end();
if(!cnt.empty())
{
// there is no neater way of determining if
// an element is the last that works across
// std lib containers
--last;
}
else
{
do_pg_empty_element(cnt, append, true_type());
return;
}
append << "{";
for(it i = cnt.begin(); i != cnt.end(); ++i)
{
do_pg_array_element(*i, append, is_container<contained_type>());
if(i != last)
append << ", ";
}
append << "}";
}
template<typename container>
string to_pg_array_constr(const container& cnt)
{
stringstream result;
do_pg_array_element(cnt, result, true_type());
return result.str();
}
int main()
{
vector<string> a;
list<vector<int> > b;
for(int i = 0; i < 10; ++i)
{
a.push_back("Peter's vector");
vector<int> sss;
sss.push_back(0);
sss.push_back(1);
sss.push_back(2);
b.push_front(sss);
}
cout << "a: " << to_pg_array_constr(a) << endl << endl;
cout << "b: " << to_pg_array_constr(b) << endl << endl;
connection conn("dbname=postgres");
work test(conn, "test");
conn.prepare("unnest", "SELECT unnest($1::text[][])")("text[][]");
result r = test.prepared("unnest")(to_pg_array_constr(a)).exec();
for(result::const_iterator c = r.begin(); c != r.end(); ++c)
{
cout << c[0].as(string()) << endl;
}
return 0;
}
// c++ to_pg_array.cpp -L/usr/local/pgsql/lib -lpqxx -lpq