wiki:WikiStart

Version 12 (modified by jtv, 14 years ago) (diff)

--

Welcome to the New Site

This project is just in the process of moving to this new site, from its old location at http://gborg.postgresql.org/project/libpqxx/ so don't be surprised if some things are still missing. Also, the new location uses Subversion for revision control instead of the older CVS. See UsingThisSite for more details on various ways to access the source code etc., and the development projects overview page for other development projects hosted on this site. Complete source tarballs are available on the DownloadPage.

The old project site also has two mailing lists for discussion and announcements related to libpqxx.

Sales Pitch

libpqxx is the official C++ API for writing client programs that talk to the PostgreSQL database management system (if that's too verbose, call it by its shorter name, postgres).

I hope you will find libpqxx flexible but easy to use. Not everything about it is easy, but at least there is a tendency to stick to the kinds of complexity that you are used to as a C++ programmer. Query results do not have their own "get next row" interfaces and so on; instead, they provide iterator classes that let you treat the result as a standard C++ container, just like the ones defined by the STL. Streams are also supported where it makes sense, and fields can be read into variables using conversion functions that are implemented as templates.

Also, simple libpqxx programs tend to be less complex than equivalent Java code while having more flexibility.

Many similar libraries have preceded libpqxx and perhaps many will follow. Below are some reasons why I believe libpqxx is worth your while.

  1. Language conformance. It tries to make sensible use of modern C++ features such as templates, standard exceptions, and various kinds of iterators to integrate more comfortably with the language. Where possible, libpqxx blends in with the standard library and the STL in particular.
  2. Structure. It also tries to make it easier for you to write robust, correct code that deals elegantly with various kinds of error conditions. This helps the library detect many problems at compile time instead of at runtime, or during a normal test instead of just in rare corner cases.
  3. Power. Built-in features such as automatic connection restoration and transaction management free you from the low-level chores that tend to take up too much time and go wrong just when you need them most.
  4. Flexibility. Despite the above, this is not an application framework. You won't be forced to squeeze your code into a poorly matched, poorly documented event loop. There are no home-grown string or exception classes. The library lives in its own namespace and completely hides all symbols of the underlying C API library, so it's less likely to clash with other libraries.
  5. Generic programming. Object-orientation is a fine thing, but let's not get obsessed. Functions are used where they make more sense than classes. Inheritance is used internally, but you are not expected to derive your own classes from libpqxx classes except in one or two specific and useful design patterns. Even then, your own code will be isolated in a well-understood environment.

If your impression is that libpqxx is nothing special, that everything about it is obvious or unsurprising, then that means it does its job.

More about libpqxx

It's not very recent, but Poul Höcherl has written a nice article on OSDN about libpqxx. And around the same time, Markus Jais wrote a particularly good German article for Linux Enterprise--but unfortunately it is not available in the online edition. The source code to his examples is available though.

For a quick overview, you may also want to look at the attached slides for a presentation I gave at the FOSDEM conference in Brussels, February 2003. These are not very verbose though; I prefer to avoid long texts and endless lists of bullet points in presentations, focusing on the spoken word and a few illustrations and reminders instead. Also, this presentation was based on the old libpqxx 1.x API which is now obsolete.

Users' Comments

Here are just some flattering comments from developers using libpqxx:

  • I love the job you've done on libpqxx - the class layouts just make perfect sense to me. I've also learned a lot about writing STL-compatible classes by looking at your code, thanks. -- Murphy Pope
  • I started playing around with the pqxx library last night and I'm quite impressed by how easy it is to perform simple db tasks (The test programs helps a whole lot too). -- Hannes Wagener
  • I must say I'm really impressed with the clean, good-looking code for a simple test program and with the STL container approach.
  • Congrats on your library, it is a pleasure to work with well done, open code.

Technical Overview

The first thing you're likely to notice in programming with libpqxx is that unlike other libraries, it revolves entirely around transactions. Transactions are a central concept in database management systems, but they are widely underappreciated among application developers. Another well-known open source database system, MySQL, never even got around to implementing them at all in their own engine, relying on a third-party replacement engine (now owned by Oracle) to provide this functionality instead. It may sometimes be possible to build limited applications reliably without serious use of transactions, but applications that don't use them are usually written that way because the developers aren't fully aware of the risks they are taking, and any data loss is rare or small enough not to be noticed. That kind of design was not considered acceptable for libpqxx.

With conventional database APIs, you issue commands and queries to a database session or connection, and optionally create the occasional transaction. In libpqxx you start a transaction inside the connection first, do your SQL work using that transaction, then commit it when it's complete. There are several types of transactions with various "quality of service" properties; if you don't really want to use transactions at all, one of the available transaction types is called nontransaction and provides classic, nontransactional behaviour.

Every command or query issues a result object, which is really a smart pointer so it can be copied around without incurring much cost in terms of performance. No need to write special code to check these for success; error conditions are converted to regular C++ exceptions. Result objects can be kept around for as long as they are needed, completely separate from the connections and transactions that originated them.