NOTICES FOR USERS UPGRADING FROM 2.0 AND 2.1 VERSIONS TO 2.2.0 OR LATER The default installation location has changed from /usr/local/pqxx to /usr/local which should make it easier to run programs linked to libpqxx. If you upgrade, be sure to remove your old /usr/local/pqxx is removed, or at least remove it from your header and library paths when compiling your libpqxx programs. The configure script no longer requires the --with-postgres options, nor does it recognize them. Instead, it finds the PostgreSQL headers and libraries by running Postgres' pg_config script. This should have been installed in the binaries directory of your PostgreSQL installation; make sure it's in your command path before running the libpqxx configure script. IMPORTANT NOTICE FOR USERS UPGRADING TO 1.9.0 OR LATER FROM OLDER VERSIONS Version 1.9.0 marks a radical change in the library, preparatory to the 2.0.0 release2003. These may require changes in your code; see the NEWS file for quick overview of the changes. Most of these are also relevant for users upgrading from 1.x to 2.x versions of the library. Not all the changes will be of immediate importance to you; where possible, typedefs have been provided to maintain backwards compatibility. In some cases however, your existing code may fail to compile, or changes may be needed to stay compatible with future versions of libpqxx. 1. The Great Renaming Practically all classes have been renamed to fully lower-case names. This was requested by several users, and should help stylistic integration with the C++ Standard Library. Typedefs have been provided where necessary, so no immediate changes in your code are needed on that score (although eventually of course the typedefs will be phased out); however, don't be surprised if class names are spelled differently in the documentation or in compiler messages than you're used to. 2. The Transformed Transaction Taxonomy (TTT) The old Transaction hierarchy has been transformed to accomodate transaction isolation levels as compile-time type properties. Also, there is now a separate dbtransaction base class to indicate that a subclass opens a real transaction on the backend. As you may have guessed, nontransaction is the only type of transaction implementation that isn't derived from dbtransaction. The new root of the inheritance tree is transaction_base. Isolation levels are modeled as template arguments to the transaction types that support them, i.e. those classes derived from dbtransaction. This makes it easy to adapt if the set of isolation levels implemented by the underlying database should ever change. To limit the amount of inlined code, these newly templatized classes (i.e. transaction and robusttransaction) are not derived directly from dbtransaction. Instead, their implementations are mostly contained in basic_transaction and basic_robusttransaction respectively. The template classes inherit their implementations from these classes and only add the minimal changes required to set their isolation levels. To express that a function requires a robusttransaction of any isolation level, for instance, make its parameter refer to a basic_robusttransaction. The database's default isolation level is "read committed," which means that a transaction will read newly changed values as they become available from other transactions as they commit. PostgreSQL also implements "serializable," which completely isolates each transaction from seeing changes made by other transactions while it is active. The drawback of the serializable level is that the database may occasionally need to abort the transaction because its "snapshot" view of the database has become impossible to maintain. Using libpqxx transactors will isolate you from this concern. The old Transaction name is now typedef'ed to mean transaction; to get a serializable one, declare a transaction. The same goes for robusttransaction. To use the default isolation level, just write transaction<> (or, naturally, robusttransaction<>). This will use the default template parameter, which is read_committed. For transaction<>, which you'll usually want to use, there is also a convenience typedef called "work." Isolation levels are defined in the new header file pqxx/isolation.h. 3. If you use Cursor or CachedResult... These classes have contained a serious bug for some time now, which is related to the transaction isolation levels described above. Even if you don't want to upgrade right away, please try to avoid the "absolute positioning" feature of Cursor, and avoid CachedResult altogether. Either will be safe if you only read your result set once, in a strict forward-only manner, but please consider upgrading libpqxx. Newer version ensure that your code will not build until you fix the problem. The problem is this: due to the database's default transaction isolation level of "read committed," it is possible for another transaction to modify the contents of your query's result set as you access them. The Cursor class in recent versions of libpqxx knew how to keep track of their absolute position to let you scroll directly to a given row, or to determine the size of the result set. If another transaction modifies the rows you're interested in, however, that may affect the number of rows in your result set and confuse your cursor object's positioning logic. The CachedResult class was built on top of Cursor's absolute positioning functionality, and so has the same problem. TTT to the rescue. The new transaction hierarchy allows the constructors for cursor and cachedresult to demand that they be passed a transaction with isolation level "serializable." Failure to do so will yield a compile-time or link-time error for the symbol error_permitted_isolation_level(). If you want to continue using cursors and cachedresults the way you were used to, you'll need to replace the relevant transactions with ones declared as serializable: transaction or robusttransaction. This may require some restructuring or templatization of your program in some cases, because the constructors for cursor and cachedresult must be able to see the correct transaction isolation level at compile time, but I hope you'll agree it was the only solution that was both safe and efficient. The offending functionality will be spliced out of the cursor class; in fact, the class may disappear altogether and be replaced by a set of iterator-based interfaces; random-access iterators will only be available in serializable transactions, and some optimizations will be possible for forward-only iterators. The difference between updateable and read-only cursors may be reflected as a distinction between regular iterators and const_iterators. 4. If you use Transactors The old way of setting a transaction type as your transactor's "quality of service," by overriding the nested typedef for "argument_type," has been deprecated. It will still work as far as I can make out, but may at some point in the future development of libpqxx fail to do what you expect. There will be no compile-time warning of this, so please inspect your transactors manually. The new way to set a transactor's quality of service is to pass the desired transaction type as a template argument. The old Transactor name is defined to mean "transactor<>", maintaining the old default of Transaction (which is now really a transaction). To replace this with, say, a nontransaction write: class UnsafeTransactor : public transactor For a super-robust, highly reliable transactor, write: class SafeTransactor : public transactor > Note the space between the two closing angled-brackets: "> >" instead of merely ">>". This is due to an ambiguity in the C++ syntax. Without the whitespace, the two consecutive larger-than signs would be parsed as a >> (shift-right) operator.