Thread: libpq++
Is anyone maintaining libpq++? My patches are beginning to seriously overlap each other, making it hard to submit them individually. If there's nobody out there, I'd be willing to maintain this code and make more extensive changes. In particular, I would like to: - introduce exceptions instead of manual checking, as suggested in TODO;- update the manual;- review all the little consts,bools, explicits and such;- replace PgTransaction by a more fine-grained and exception-safe mechanism outside thePgDatabase hierarchy;- provide STL-conformant interfaces for iterating over result sets;- allow fields to be accessedin a type-safe manner;- ensure clean compilation under g++ 3.0;- bring functionality up-to-date with libpq if, as& where needed Would that be OK? Jeroen
Hi Jeroen, I'm very interested in a total revamp of the C++ API. I'd like to mirror the roguewave dbtools++ api in some ways as well as building a STL compliant interface. Would you be interested in working together on this? Cheers, Randy On Wed, 7 Mar 2001, J. T. Vermeulen wrote: > Is anyone maintaining libpq++? My patches are beginning to seriously > overlap each other, making it hard to submit them individually. > > If there's nobody out there, I'd be willing to maintain this code and > make more extensive changes. In particular, I would like to: > > - introduce exceptions instead of manual checking, as suggested in TODO; > - update the manual; > - review all the little consts, bools, explicits and such; > - replace PgTransaction by a more fine-grained and exception-safe > mechanism outside the PgDatabase hierarchy; > - provide STL-conformant interfaces for iterating over result sets; > - allow fields to be accessed in a type-safe manner; > - ensure clean compilation under g++ 3.0; > - bring functionality up-to-date with libpq if, as & where needed > > Would that be OK? > > > Jeroen > > > ---------------------------(end of broadcast)--------------------------- > TIP 6: Have you searched our list archives? > > http://www.postgresql.org/search.mpl > > Randy Jonasz Software Engineer Click2net Inc. Web: http://www.click2net.com Phone: (905) 271-3550 "You cannot possibly pay a philosopher what he's worth, but try your best" -- Aristotle
Sounds great. We are in 7.1 beta hold, so keep going and we can apply anything you have once we start on 7.2. > Is anyone maintaining libpq++? My patches are beginning to seriously > overlap each other, making it hard to submit them individually. > > If there's nobody out there, I'd be willing to maintain this code and > make more extensive changes. In particular, I would like to: > > - introduce exceptions instead of manual checking, as suggested in TODO; > - update the manual; > - review all the little consts, bools, explicits and such; > - replace PgTransaction by a more fine-grained and exception-safe > mechanism outside the PgDatabase hierarchy; > - provide STL-conformant interfaces for iterating over result sets; > - allow fields to be accessed in a type-safe manner; > - ensure clean compilation under g++ 3.0; > - bring functionality up-to-date with libpq if, as & where needed > > Would that be OK? > > > Jeroen > > > ---------------------------(end of broadcast)--------------------------- > TIP 6: Have you searched our list archives? > > http://www.postgresql.org/search.mpl > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
> Is anyone maintaining libpq++? My patches are beginning to seriously > overlap each other, making it hard to submit them individually. > > If there's nobody out there, I'd be willing to maintain this code and > make more extensive changes. In particular, I would like to: > > - introduce exceptions instead of manual checking, as suggested in TODO; > - update the manual; > - review all the little consts, bools, explicits and such; > - replace PgTransaction by a more fine-grained and exception-safe > mechanism outside the PgDatabase hierarchy; > - provide STL-conformant interfaces for iterating over result sets; > - allow fields to be accessed in a type-safe manner; > - ensure clean compilation under g++ 3.0; > - bring functionality up-to-date with libpq if, as & where needed > > Would that be OK? Also, would you review this? ftp://candle.pha.pa.us/pub/postgresql/libpq++.mbox and merge any valuable changes into your copy of the code. Much of it is already in there. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
"J. T. Vermeulen" <jtv@cistron-office.nl> writes: > Is anyone maintaining libpq++? No one's been seen doing any major work on it in quite a while, AFAIR. > If there's nobody out there, I'd be willing to maintain this code and > make more extensive changes. In particular, I would like to: Go for it! regards, tom lane
On Wed, 07 Mar 2001, Bruce Momjian wrote: > > Would that be OK? > > Also, would you review this? > > ftp://candle.pha.pa.us/pub/postgresql/libpq++.mbox > > and merge any valuable changes into your copy of the code. Much of it > is already in there. Will do. Can I take it there have been no other changes between 7.0.3 and 7.2 as far as libpq++ is concerned, so I can continue to work with the version I have? Jeroen
> On Wed, 07 Mar 2001, Bruce Momjian wrote: > > > > Would that be OK? > > > > Also, would you review this? > > > > ftp://candle.pha.pa.us/pub/postgresql/libpq++.mbox > > > > and merge any valuable changes into your copy of the code. Much of it > > is already in there. > > Will do. Can I take it there have been no other changes between 7.0.3 and 7.2 > as far as libpq++ is concerned, so I can continue to work with the version I > have? I don't think much has been done with 7.1 libpq++. I would download the snapshot and do a diff against 7.0.3 to be sure. Attached are the changes I see since 7.0.0. They are very minor. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 Index: libpq++.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/libpq++.h,v retrieving revision 1.9 retrieving revision 1.10 diff -c -r1.9 -r1.10 *** libpq++.h 2000/04/22 22:39:15 1.9 --- libpq++.h 2001/01/24 19:43:32 1.10 *************** *** 13,22 **** * in the build environment the individual include files are not * yet installed in a subdirectory. * ! * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * ! * $Id: libpq++.h,v 1.9 2000/04/22 22:39:15 tgl Exp $ * *------------------------------------------------------------------------- */ --- 13,22 ---- * in the build environment the individual include files are not * yet installed in a subdirectory. * ! * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * ! * $Id: libpq++.h,v 1.10 2001/01/24 19:43:32 momjian Exp $ * *------------------------------------------------------------------------- */ Index: pgconnection.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgconnection.cc,v retrieving revision 1.9 retrieving revision 1.10 diff -c -r1.9 -r1.10 *** pgconnection.cc 2000/04/22 22:39:15 1.9 --- pgconnection.cc 2000/07/27 19:44:01 1.10 *************** *** 10,16 **** * Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION ! * $Header: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgconnection.cc,v 1.9 2000/04/22 22:39:15 tglExp $ * *------------------------------------------------------------------------- */ --- 10,16 ---- * Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION ! * $Header: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgconnection.cc,v 1.10 2000/07/27 19:44:01 momjianExp $ * *------------------------------------------------------------------------- */ *************** *** 46,61 **** // Close the connection only if needed // This feature will most probably be used by the derived classes that // need not close the connection after they are destructed. ! if ( pgCloseConnection ) { if(pgResult) PQclear(pgResult); if(pgConn) PQfinish(pgConn); } } // PgConnection::connect // establish a connection to a backend ConnStatusType PgConnection::Connect(const char* conninfo) { // Connect to the database pgConn = PQconnectdb(conninfo); --- 46,77 ---- // Close the connection only if needed // This feature will most probably be used by the derived classes that // need not close the connection after they are destructed. ! CloseConnection(); ! } ! ! ! // PgConnection::CloseConnection() ! // close down the connection if there is one ! void PgConnection::CloseConnection() ! { ! // if the connection is open, close it first ! if ( pgCloseConnection ) { if(pgResult) PQclear(pgResult); + pgResult=NULL; if(pgConn) PQfinish(pgConn); + pgConn=NULL; + pgCloseConnection=0; } } + // PgConnection::connect // establish a connection to a backend ConnStatusType PgConnection::Connect(const char* conninfo) { + // if the connection is open, close it first + CloseConnection(); + // Connect to the database pgConn = PQconnectdb(conninfo); Index: pgconnection.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgconnection.h,v retrieving revision 1.7 retrieving revision 1.10 diff -c -r1.7 -r1.10 *** pgconnection.h 2000/04/22 22:39:15 1.7 --- pgconnection.h 2001/02/10 02:31:30 1.10 *************** *** 10,19 **** * NOTES * Currently under construction. * ! * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * ! * $Id: pgconnection.h,v 1.7 2000/04/22 22:39:15 tgl Exp $ * *------------------------------------------------------------------------- */ --- 10,19 ---- * NOTES * Currently under construction. * ! * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * ! * $Id: pgconnection.h,v 1.10 2001/02/10 02:31:30 tgl Exp $ * *------------------------------------------------------------------------- */ *************** *** 38,44 **** #endif extern "C" { ! #include "postgres.h" #include "libpq-fe.h" } --- 38,44 ---- #endif extern "C" { ! #include "postgres_fe.h" #include "libpq-fe.h" } *************** *** 81,86 **** --- 81,87 ---- protected: ConnStatusType Connect(const char* conninfo); + void CloseConnection(); string IntToString(int); // Default constructor is only available to subclasses PgConnection(); Index: pgcursordb.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgcursordb.h,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** pgcursordb.h 2000/04/22 22:39:15 1.5 --- pgcursordb.h 2001/01/24 19:43:32 1.6 *************** *** 10,20 **** * NOTES * Currently under construction. * ! * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * * ! * $Id: pgcursordb.h,v 1.5 2000/04/22 22:39:15 tgl Exp $ * *------------------------------------------------------------------------- */ --- 10,20 ---- * NOTES * Currently under construction. * ! * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ! * $Id: pgcursordb.h,v 1.6 2001/01/24 19:43:32 momjian Exp $ * *------------------------------------------------------------------------- */ Index: pgdatabase.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgdatabase.h,v retrieving revision 1.8 retrieving revision 1.9 diff -c -r1.8 -r1.9 *** pgdatabase.h 2000/04/22 22:39:15 1.8 --- pgdatabase.h 2001/01/24 19:43:32 1.9 *************** *** 10,20 **** * NOTES * Currently under construction. * ! * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * * ! * $Id: pgdatabase.h,v 1.8 2000/04/22 22:39:15 tgl Exp $ * *------------------------------------------------------------------------- */ --- 10,20 ---- * NOTES * Currently under construction. * ! * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ! * $Id: pgdatabase.h,v 1.9 2001/01/24 19:43:32 momjian Exp $ * *------------------------------------------------------------------------- */ Index: pglobject.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pglobject.h,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** pglobject.h 2000/04/22 22:39:15 1.5 --- pglobject.h 2001/01/24 19:43:32 1.6 *************** *** 7,17 **** * declaration of the PGlobj class. * PGlobj encapsulates a large object interface to Postgres backend * ! * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * * ! * $Id: pglobject.h,v 1.5 2000/04/22 22:39:15 tgl Exp $ * *------------------------------------------------------------------------- */ --- 7,17 ---- * declaration of the PGlobj class. * PGlobj encapsulates a large object interface to Postgres backend * ! * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ! * $Id: pglobject.h,v 1.6 2001/01/24 19:43:32 momjian Exp $ * *------------------------------------------------------------------------- */ Index: pgtransdb.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/pgtransdb.h,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** pgtransdb.h 2000/04/22 22:39:15 1.5 --- pgtransdb.h 2001/01/24 19:43:32 1.6 *************** *** 10,20 **** * NOTES * Currently under construction. * ! * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * * ! * $Id: pgtransdb.h,v 1.5 2000/04/22 22:39:15 tgl Exp $ * *------------------------------------------------------------------------- */ --- 10,20 ---- * NOTES * Currently under construction. * ! * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ! * $Id: pgtransdb.h,v 1.6 2001/01/24 19:43:32 momjian Exp $ * *------------------------------------------------------------------------- */ Index: examples/Makefile =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/Makefile,v retrieving revision 1.10 retrieving revision 1.12 diff -c -r1.10 -r1.12 *** examples/Makefile 2000/03/02 02:00:59 1.10 --- examples/Makefile 2000/06/17 00:10:20 1.12 *************** *** 15,33 **** #CXXFLAGS= $(CFLAGS) -Wno-error -Wno-unused -Wl,-Bdynamic CXXFLAGS= $(CFLAGS) ! INCLUDE_OPT= -I$(HEADERDIR) - CXXFLAGS+= $(INCLUDE_OPT) - LDFLAGS+= -L$(LIBPQDIR) -lpq++ - - # - # And where libpq goes, so goes the authentication stuff... - # - ifdef KRBVERS - LDFLAGS+= $(KRBLIBS) - CXXFLAGS+= $(KRBFLAGS) - endif PROGS= testlibpq0 testlibpq1 testlibpq2 testlibpq3 \ testlibpq4 testlibpq5 testlibpq6 testlo --- 15,23 ---- #CXXFLAGS= $(CFLAGS) -Wno-error -Wno-unused -Wl,-Bdynamic CXXFLAGS= $(CFLAGS) ! CXXFLAGS+= -I$(HEADERDIR) LDFLAGS+= -L$(LIBPQDIR) -lpq++ PROGS= testlibpq0 testlibpq1 testlibpq2 testlibpq3 \ testlibpq4 testlibpq5 testlibpq6 testlo Index: examples/testlibpq0.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq0.cc,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** examples/testlibpq0.cc 1999/12/03 18:28:32 1.5 --- examples/testlibpq0.cc 2000/05/29 21:25:04 1.6 *************** *** 9,21 **** * * * IDENTIFICATION ! * $Header: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq0.cc,v 1.5 1999/12/03 18:28:32momjian Exp $ * *------------------------------------------------------------------------- */ #include <iostream.h> ! #include <libpq++.h> int main() { --- 9,21 ---- * * * IDENTIFICATION ! * $Header: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq0.cc,v 1.6 2000/05/29 21:25:04momjian Exp $ * *------------------------------------------------------------------------- */ #include <iostream.h> ! #include "libpq++.h" int main() { Index: examples/testlibpq1.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq1.cc,v retrieving revision 1.7 retrieving revision 1.8 diff -c -r1.7 -r1.8 *** examples/testlibpq1.cc 2000/04/25 21:00:29 1.7 --- examples/testlibpq1.cc 2000/05/29 21:25:04 1.8 *************** *** 8,14 **** #include <iostream.h> #include <iomanip.h> ! #include <libpq++.h> int main() { --- 8,14 ---- #include <iostream.h> #include <iomanip.h> ! #include "libpq++.h" int main() { Index: examples/testlibpq2.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq2.cc,v retrieving revision 1.8 retrieving revision 1.9 diff -c -r1.8 -r1.9 *** examples/testlibpq2.cc 2000/04/25 21:00:29 1.8 --- examples/testlibpq2.cc 2000/05/29 21:25:04 1.9 *************** *** 8,14 **** #include <iostream.h> #include <iomanip.h> ! #include <libpq++.h> int main() { --- 8,14 ---- #include <iostream.h> #include <iomanip.h> ! #include "libpq++.h" int main() { Index: examples/testlibpq3.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq3.cc,v retrieving revision 1.8 retrieving revision 1.9 diff -c -r1.8 -r1.9 *** examples/testlibpq3.cc 2000/04/25 21:00:29 1.8 --- examples/testlibpq3.cc 2000/05/29 21:25:04 1.9 *************** *** 9,15 **** #include <iostream.h> #include <iomanip.h> ! #include <libpq++.h> int main() { --- 9,15 ---- #include <iostream.h> #include <iomanip.h> ! #include "libpq++.h" int main() { Index: examples/testlibpq4.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq4.cc,v retrieving revision 1.6 retrieving revision 1.7 diff -c -r1.6 -r1.7 *** examples/testlibpq4.cc 2000/04/25 21:00:29 1.6 --- examples/testlibpq4.cc 2000/05/29 21:25:04 1.7 *************** *** 19,25 **** * */ #include <iostream.h> ! #include <libpq++.h> #include <stdlib.h> main() --- 19,25 ---- * */ #include <iostream.h> ! #include "libpq++.h" #include <stdlib.h> main() Index: examples/testlibpq5.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq5.cc,v retrieving revision 1.6 retrieving revision 1.7 diff -c -r1.6 -r1.7 *** examples/testlibpq5.cc 2000/04/25 21:00:29 1.6 --- examples/testlibpq5.cc 2000/05/29 21:25:04 1.7 *************** *** 27,33 **** * */ #include <iostream.h> ! #include <libpq++.h> #include <stdlib.h> extern "C" { #include "postgres.h" // for Postgres types --- 27,33 ---- * */ #include <iostream.h> ! #include "libpq++.h" #include <stdlib.h> extern "C" { #include "postgres.h" // for Postgres types Index: examples/testlibpq6.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlibpq6.cc,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** examples/testlibpq6.cc 2000/04/25 21:00:29 1.5 --- examples/testlibpq6.cc 2000/05/29 21:25:04 1.6 *************** *** 5,11 **** * */ #include <iostream.h> ! #include <libpq++.h> #include <stdlib.h> main() --- 5,11 ---- * */ #include <iostream.h> ! #include "libpq++.h" #include <stdlib.h> main() Index: examples/testlo.cc =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlo.cc,v retrieving revision 1.7 retrieving revision 1.8 diff -c -r1.7 -r1.8 *** examples/testlo.cc 2000/04/25 21:00:29 1.7 --- examples/testlo.cc 2000/05/29 21:25:04 1.8 *************** *** 7,18 **** * * * IDENTIFICATION ! * $Header: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlo.cc,v 1.7 2000/04/25 21:00:29 momjianExp $ * *------------------------------------------------------------------------- */ #include <iostream.h> ! #include <libpq++.h> #include <stdlib.h> int main(int argc, char **argv) --- 7,18 ---- * * * IDENTIFICATION ! * $Header: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq++/examples/testlo.cc,v 1.8 2000/05/29 21:25:04 momjianExp $ * *------------------------------------------------------------------------- */ #include <iostream.h> ! #include "libpq++.h" #include <stdlib.h> int main(int argc, char **argv)
"J. T. Vermeulen" <jtv@cistron-office.nl> writes: > Will do. Can I take it there have been no other changes between 7.0.3 > and 7.2 as far as libpq++ is concerned, so I can continue to work with > the version I have? No, you shouldn't take it. For one thing, Peter E. has been reorganizing the configure/build process, and that has impacted pretty nearly everything. The changes aren't likely to be extensive, but you'd still be facing a merge task when you are ready to submit diffs. Seems like you might as well try to avoid that by starting from something more current than 7.0.3. 7.1beta5 would probably be a reasonable starting point. regards, tom lane
On Wed, 07 Mar 2001, Randy Jonasz wrote: > I'm very interested in a total revamp of the C++ API. I'd like to mirror > the roguewave dbtools++ api in some ways as well as building a STL > compliant interface. Would you be interested in working together on this? Very. I'm sure they must've done a good job, seeing they have Todd Veldhuys (the first to publish C++ expression templates) on board. But provided, of course, that libpq++ can remain a reasonably light wrapper around the C interface--or at least spend most of its code adapting the C API to the way C++ wants things to be done. First however I'll have to merge the changes from at least the three groups of diffs that I have already. But for when the time comes, I'd be delighted if you could point me to a brief introduction somewhere that tells me at a quick glance what the general ideas behind the RogueWave API is. Oh, did I mention I was interested in something short and nutshell-contained? ;-) Jeroen
On Wed, 07 Mar 2001, Tom Lane wrote: > No, you shouldn't take it. For one thing, Peter E. has been > reorganizing the configure/build process, and that has impacted pretty > nearly everything. The changes aren't likely to be extensive, but you'd > still be facing a merge task when you are ready to submit diffs. Seems > like you might as well try to avoid that by starting from something more > current than 7.0.3. > > 7.1beta5 would probably be a reasonable starting point. Whew--thanks! Indeed, I'm just reading through the CVS overview and I see it now. Downloadink 7.1b5 & lookink forward to more merging... Jeroen
That's great! I think the current C++ API could be improved by a bottom up rewrite. This would facilitate a true OOP design and permit code such as: pgdatabase db( "coninfo" ); pgresult res = db.query( "sql"); psgresult::iterator row = res.begin(); pgresult::iterator end = res.end(); while( start < end ) { *row >> var1 >> var2; //or var1 = row["colname"]; //or var1 = row[col]; } I'd like to see the result container comply with STL standard so results can be used with the STL algorithms or copied into other containers. I've talked about this in the past, and agree that lazy conversion of values into their appropriate types would be of use as well. what do you think? Cheers, Randy On Thu, 8 Mar 2001, J.T.Vermeulen wrote: > On Wed, 07 Mar 2001, Randy Jonasz wrote: > > > I'm very interested in a total revamp of the C++ API. I'd like to mirror > > the roguewave dbtools++ api in some ways as well as building a STL > > compliant interface. Would you be interested in working together on this? > > Very. I'm sure they must've done a good job, seeing they have Todd Veldhuys > (the first to publish C++ expression templates) on board. But provided, of > course, that libpq++ can remain a reasonably light wrapper around the C > interface--or at least spend most of its code adapting the C API to the way > C++ wants things to be done. > > First however I'll have to merge the changes from at least the three groups > of diffs that I have already. But for when the time comes, I'd be delighted > if you could point me to a brief introduction somewhere that tells me at a > quick glance what the general ideas behind the RogueWave API is. Oh, did I > mention I was interested in something short and nutshell-contained? ;-) > > > Jeroen > > > Randy Jonasz Software Engineer Click2net Inc. Web: http://www.click2net.com Phone: (905) 271-3550 "You cannot possibly pay a philosopher what he's worth, but try your best" -- Aristotle
On Thu, 08 Mar 2001, Randy Jonasz wrote: > psgresult::iterator row = res.begin(); > pgresult::iterator end = res.end(); > > while( start < end ) { > > *row >> var1 >> var2; > //or > var1 = row["colname"]; > //or > var1 = row[col]; > > } Right! For now I wouldn't so far as to make the result sets modifiable though. That would be opening a whole new can of worms. Also, there is the issue of type safety to be dealt with. I think that has priority over operator << on result sets. So initially at least, const_iterators only. But definitely yes on the sequence algorithms, and perhaps we could find a meaningful way to work in associative behaviour as well. One side effect of having a type-safe interface would be that the COPY command no longer requires complete compile-time knowledge of a table's definition. If COPY is faster than INSERT for mass inserts (I have no idea whether it is, but it might just skip a bit of parsing on the server side and send less data over the wire), that would allow for faster data insertion while keeping the program reasonably robust w.r.t. schema changes. Another thing that could be done is to also have a more restricted interface where you don't send SQL at all, and all operations are encoded in the class interface. That might make it possible to have more-or-less generic failover built into the frontend (automatically restore active triggers when connection to server is recovered, stuff like that). Jeroen
I am not so much the libpq++ maintainer as the one who applies people's patches. There is an interfaces list that would love to hear about your work. I am CC'ing them on this. We certainly need libpq++ improvements. If you would prefer not to deal with the interfaces list, send something to me and I will send it over there. > Bruce - > Are you the current maintainer of libpq++? I've got some stuff that > would make it a much more inheritable class (at least from my perspective), > and wouldn't break anything. If you're interested, let me know, and I'll > outline it for you. > > -justinb > > -- > Justin Banks Tricord, Inc. justinb@tricord.com > Education... has produced a vast population able to read but unable to > distinguish what is worth reading. -G. M. Trevelyan > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
On Sun, 29 Apr 2001, Bruce Momjian wrote: > I am not so much the libpq++ maintainer as the one who applies people's > patches. There is an interfaces list that would love to hear about your > work. I am CC'ing them on this. We certainly need libpq++ > improvements. If you would prefer not to deal with the interfaces list, > send something to me and I will send it over there. Working on rewrite--can do some serious work once my new laptop arrives. Jeroen
>>>>> "Bruce" == Bruce Momjian <pgman@candle.pha.pa.us> writes: Bruce> I am not so much the libpq++ maintainer as the one who applies Bruce> people's patches. There is an interfaces listthat would love to Bruce> hear about your work. I am CC'ing them on this. We certainly need Bruce> libpq++ improvements. If you would prefer not to deal with the Bruce> interfaces list, send something to me and I will send it overthere. Here's what I've done. The following code will create a number of different connections to the B.E., even though there's no reason to have more than one. This prevents one from inheriting PgDatabase, and then creating an array of 100 or so of those objects. #include <iostream.h> #include <stdlib.h> #include <libpq++.h> class base : public PgDatabase { public: base() { cout << "base class instantiating" << endl; Connect("host=dbdbname=golem user=golemadmin password=bleen"); } virtual ~base() { cout << "Base class destructing"<< endl; } }; class derived : public base { public: derived() { cout << "derived class instantiating" << endl; } ~derived() { cout << "derived class destructing" << endl; } }; int main(int argc, char* argv[]) { int cnt, tuples; derived* classes, *ptr; derived single; if(argc > 1) cnt = atoi(argv[1]); else cnt = 5; cout << "getting array of " << cnt << " objects" << endl; classes = new derived[cnt]; cout << "array allocated, sleeping for validation" << endl; sleep(5); for(int i = 0; i < cnt; i++) { cout << "testingobject " << i << endl; ptr = &(classes[i]); ptr->Exec("select * from defaults"); tuples = ptr->Tuples(); cout << "got " << tuples << " tuples" << endl; for(int j = 0; j < tuples; j++) { cout << "4th field is " << ptr->GetValue(j,4) << endl; } } delete[] classes; cout << "aggregates deleted" << endl; single.Exec("select table_name from tables limit 1"); cout << "exec of single finished"<< endl; cout << "value is " << single.GetValue(0, 0) << endl; exit(0); } What I'd like to have happen is for a total of one connection to the database to be made, and have all these objects share that connection transparently. I made this happen by using a shared memory segment to store the connection pointer. Here's the diff. It doesn't seem to break anything, but then again, my coverage is rather limited at this point. Diff follows : --- pgconnection.cc.orig Sun Apr 29 16:09:02 2001 +++ pgconnection.cc Sun Apr 29 21:35:36 2001 @@ -17,7 +17,6 @@#include "pgconnection.h" -// ****************************************************************//// PgConnection Implementation @@ -54,7 +53,15 @@// close down the connection if there is onevoid PgConnection::CloseConnection() { - // if the connection is open, close it first +#if USING_SYSV_IPC == 1 + struct shmid_ds shminfo; + + shmctl(shmid, IPC_STAT, &shminfo); + // + // if we're the only one left ... + // + if(shminfo.shm_nattch == 1) { +#endif if ( pgCloseConnection ) { if(pgResult) PQclear(pgResult); pgResult=NULL; @@ -62,6 +69,10 @@ pgConn=NULL; pgCloseConnection=0; } +#if USING_SYSV_IPC == 1 + } + shmdt(addr); +#endif} @@ -69,11 +80,60 @@// establish a connection to a backendConnStatusType PgConnection::Connect(const char* conninfo){ +#if USING_SYSV_IPC == 1 + int key = (int)getpid(); + struct shmid_ds shminfo; +#endif + // if the connection is open, close it first CloseConnection(); // Connect to the database +#if USING_SYSV_IPC == 1 + if((shmid = shmget(key, sizeof(addr), IPC_CREAT|SHM_W|SHM_R)) >= 0) { + if((addr = (int*)shmat(shmid, 0, 0)) > 0) { + // + // now, we have our segment. If we're the first attacher, then we need + // to do the connect. If we're not the first attacher, then the + // connection is already made, we just need to check and make sure + // it's okay, connecting again if we have to. + // + if(shmctl(shmid, IPC_STAT, &shminfo) == 0) { + if(shminfo.shm_nattch == 1) { + pgConn = PQconnectdb(conninfo); + *addr = (int)pgConn; + } + else { + pgConn = (PGconn*)*addr; + if(Status() == CONNECTION_BAD) { + pgConn = PQconnectdb(conninfo); + *addr = (int)pgConn; + } + } + } + else { + // + // fallback to safe connection + // + pgConn = PQconnectdb(conninfo); + } + } + else { + // + // fallback to safe connection + // + pgConn = PQconnectdb(conninfo); + } + } + else { + // + // fallback to safe connection + // + pgConn = PQconnectdb(conninfo); + } +#else pgConn = PQconnectdb(conninfo); +#endif // Now we have a connection we must close (even if it's bad!) pgCloseConnection = 1; --- pgconnection.h.orig Sun Apr 29 16:09:54 2001 +++ pgconnection.h Sun Apr 29 17:07:57 2001 @@ -46,6 +46,15 @@using namespace std;#endif +#if HAVE_SYS_SHM_H == 1 && HAVE_SYS_IPC_H == 1 + #include <sys/types.h> + #include <sys/ipc.h> + #include <sys/shm.h> + #include <unistd.h> + #define USING_SYSV_IPC 1 +#else + #define USING_SYSV_IPC 0 +#endif// ****************************************************************// @@ -91,6 +100,9 @@// so make copy constructor and assignment op private. PgConnection(const PgConnection&); PgConnection&operator= (const PgConnection&); +#if USING_SYSV_IPC == 1 + int shmid, *addr; +#endif};#endif // PGCONNECTION_H I think that's it. I've got more at work, so I may have missed something, but I don't think so. -justinb -- Justin Banks @ home Distrust any enterprise that requires new clothes. -Thoreau
>>>>> "Bruce" == Bruce Momjian <pgman@candle.pha.pa.us> writes: Bruce> I am not so much the libpq++ maintainer as the one who applies Bruce> people's patches. There is an interfaces listthat would love to Bruce> hear about your work. I am CC'ing them on this. We certainly need Bruce> libpq++ improvements. If you would prefer not to deal with the Bruce> interfaces list, send something to me and I will send it overthere. As one would have expected, I've found a problem. The c++ std. says that Automatic objects are not destroyed as a result of calling exit(), and so, a automatic PgDatabase in main() (or most anywhere, actually), would not have it's destructor called during an exit(), thereby leaving junk shm. segments around. I'm not sure that an atexit can be called on a member function with no argument, so I'll do some experimenting with macros and temporary block insertion. Better ideas welcome ;) -justinb -- Justin Banks @ home 'We have no intention of shipping another bloated operating system and forcing that down the throats of our Windows customers' -- Paul Maritz, Microsoft Group Vice President
>>>>> "J" == J T Vermeulen <jtv@cistron-office.nl> writes: J> On Sun, 29 Apr 2001, Bruce Momjian wrote: >> I am not so much the libpq++ maintainer as the one who applies people's>> patches. There is an interfaces list that would love to hear about your >> work. I am CC'ing them on this. We certainly need libpq++ improvements. >> If you would prefer not to deal with the interfaces list, send something >> tome and I will send it over there. J> Working on rewrite--can do some serious work once my new laptop arrives. OK. The shmem stuff requires some more work in order for the cursor stuff to work right, anyway. -justinb -- Justin Banks Tricord, Inc. justinb@tricord.com In the good old days physicists repeated each other's experiments, just to be sure. Today they stick to FORTRAN, so that they can share each other's programs, bugs included. - Dijkstra 1975
Justin Banks <justinb@mr-boo.com> writes: > As one would have expected, I've found a problem. The c++ std. says that > Automatic objects are not destroyed as a result of calling exit(), and so, a > automatic PgDatabase in main() (or most anywhere, actually), would not have > it's destructor called during an exit(), thereby leaving junk shm. segments > around. Unless your kernel is broken, application exit will cause the backend connection to be closed, whereupon the backend will exit gracefully. I see nothing to worry about here. I'm not sure where you got this notion that clients get to touch any of Postgres' shared memory ;-) but they don't. regards, tom lane
Justin Banks <justinb@tricord.com> writes: > You're right - this only works because the shared connections all > occur in the same address space. It doesn't buy you anything between > applications, only inside an application. The problem is that there's > no way for different instantiations of classes inheriting > database-ness from the PgDatabase class to share a PGconn* unless the > PgDatabase class provides a way for different instantiations to know > that existing connections are available. And what's wrong with a static class variable for that purpose? The shmem segment looks like the hardest possible way to get the same result. regards, tom lane
Bruce Momjian <pgman@candle.pha.pa.us> writes: > I think he is creating his own shared memory area: Oh, I see. Isn't that pretty silly, considering that there's no way for such objects to share a DBconnection if they are in different application processes? Seems like a simple static variable would do the job just as well with a lot fewer portability and resource-leakage issues... regards, tom lane
> Justin Banks <justinb@mr-boo.com> writes: > > As one would have expected, I've found a problem. The c++ std. says that > > Automatic objects are not destroyed as a result of calling exit(), and so, a > > automatic PgDatabase in main() (or most anywhere, actually), would not have > > it's destructor called during an exit(), thereby leaving junk shm. segments > > around. > > Unless your kernel is broken, application exit will cause the backend > connection to be closed, whereupon the backend will exit gracefully. > I see nothing to worry about here. > > I'm not sure where you got this notion that clients get to touch any > of Postgres' shared memory ;-) but they don't. I think he is creating his own shared memory area: --------------------------------------------------------------------------- What I'd like to have happen is for a total of one connection to the database to be made, and have all these objects share that connection transparently. I made this happen by using a shared memory segment to store the connection pointer. Here's the diff. It doesn't seem to break anything, but then again, my coverage is rather limited at this point. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
>>>>> "Tom" == Tom Lane <tgl@sss.pgh.pa.us> writes: Tom> And what's wrong with a static class variable for that purpose? The Tom> shmem segment looks like the hardest possibleway to get the same Tom> result. I'm kinda embarrased to say I didn't think of that, actually. That would only mean exposing the default constructor of PgDatabase, so the derived class could put off connecting indefinitely, right? -justinb -- Justin Banks Tricord, Inc. justinb@tricord.com <Randomly selected signature here>
>>>>> "Tom" == Tom Lane <tgl@sss.pgh.pa.us> writes: Tom> Bruce Momjian <pgman@candle.pha.pa.us> writes: >> I think he is creating his own shared memory area: Tom> Oh, I see. Isn't that pretty silly, considering that there's no way Tom> for such objects to share a DBconnectionif they are in different Tom> application processes? Seems like a simple static variable would do Tom> the jobjust as well with a lot fewer portability and resource-leakage Tom> issues... If you have a class, say 'class host', that represents a table in your database, in which you are storing host information, and you want each host to also be a database object, you now have two choices, as far as I can tell. You can connect to the database in the chain of constructors somewhere, or you can put it off until you actually issue a query of some kind. Either way, you get punished quite severely if you want say, a int N = 75; host * cluster_of_boxes = new host[N](default_parameters_of_some_kind); since you either then have N connections to the backend, or every time you want to go to the DB you take a big hit. With my modification, you only get one connection to the backend, and all your host objects share it. You're right - this only works because the shared connections all occur in the same address space. It doesn't buy you anything between applications, only inside an application. The problem is that there's no way for different instantiations of classes inheriting database-ness from the PgDatabase class to share a PGconn* unless the PgDatabase class provides a way for different instantiations to know that existing connections are available. -justinb -- Justin Banks Tricord, Inc. justinb@tricord.com "The time you enjoy wasting is not wasted time." - Bertrand Russell
> Is anyone maintaining libpq++? My patches are beginning to seriously > overlap each other, making it hard to submit them individually. > > If there's nobody out there, I'd be willing to maintain this code and > make more extensive changes. In particular, I would like to: > > - introduce exceptions instead of manual checking, as suggested in TODO; > - update the manual; > - review all the little consts, bools, explicits and such; > - replace PgTransaction by a more fine-grained and exception-safe > mechanism outside the PgDatabase hierarchy; > - provide STL-conformant interfaces for iterating over result sets; > - allow fields to be accessed in a type-safe manner; > - ensure clean compilation under g++ 3.0; > - bring functionality up-to-date with libpq if, as & where needed > > Would that be OK? Sure. I can apply your patches now whenever I receive them. This will allow others to work with your changes right away. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
>> - provide STL-conformant interfaces for iterating over result sets; >> - allow fields to be accessed in a type-safe manner; This would be beautiful! I can picture myself having fun writing code like this: conn.Exec ("select ....."); copy (conn.tuples().begin(), conn.tuples().end(), ostream_iterator<tuple> (cout, "\n")); (or even conn.begin(), conn.end()) or: void custom_print_row (const tuple & row) { cout << "ID: " << row["ID"] << endl << "Name: " << row["name"] << endl << "Age: " << current_year() -row["year_born"] << endl << endl; } for_each (conn.begin(), conn.end(), custom_print_row); Things like that... Definitely nice! Carlos --
On Wed, 09 May 2001, Carlos Moreno wrote: > >> - provide STL-conformant interfaces for iterating over result sets; > >> - allow fields to be accessed in a type-safe manner; > > This would be beautiful! I can picture myself having fun > writing code like this: One drawback is there won't be any non-const iterators on queries, nor proper interaction with input iterators. Still thinking about that.
I wonder why all the string parameters and return values are expressed in the form of char * or const char * ? After some time sticking to C++ and learning to hate (even more :-)) C strings, I find myself annoyed by not being able to do this: if (db.ExecTuplesOk ("select * from products")) { for loop ...... if (db.GetValue(row, "discontinued") == "t") { cout << "Disconinued"; } Or something like this: // Get results from one query and use one field to // produce another query: string query = "select * from table where ID='" + db.GetValue (row, "prodID") + "'"; Don't you just hate it? At least the second one is not that bad, because the compiler won't let you add two pointers. But the first one slips through the compiler, who doesn't have a problem with comparing two pointers -- it can not even know that the comparison will be unconditionally false to warn you... :-( Why not just changing all the parameters and return values to `const string &' and/or `string' ? Any thoughts? Carlos --
On Wed, 16 May 2001, Carlos Moreno wrote: > I wonder why all the string parameters and return values > are expressed in the form of char * or const char * ? Performance would be one reason, I'd say. const char * is easier to tune, and of course the underlying library uses const char *'s anyway. Also of course, a string is easily constructed from a const char * but the other way needs an explicit method call. OTOH I do think you have a point w.r.t. the obvious mistakes to make, and the lack of help from the compiler in spotting them. > Why not just changing all the parameters and return > values to `const string &' and/or `string' ? One possible tradeoff (and one I was leaning towards) is to take string parameters (so passing const char [] will still work) but return const char * in case you don't need the extras of a full C++ string. Unfortunately this doesn't help with the comparison-with-string-constant problem you cite. I guess this one boils down to how important performance is. One thing I'd like to do about it in the upcoming version is to provide type-safe access to the tuples. There'd still be a GetValue() returning const char *, but you wouldn't need to use it the way you showed in your example, because you'd be able to read it simply as a native bool. Jeroen
"J. T. Vermeulen" wrote: > > On Wed, 16 May 2001, Carlos Moreno wrote: > > > I wonder why all the string parameters and return values > > are expressed in the form of char * or const char * ? > > Performance would be one reason, I'd say. Oh, c'mon!! Enough with that myth! :-) I'm probably naive and not too experienced when it comes to databases... But we're talking accessing information from disk, perhaps across a network, and you estimate that an extra allocation and copying of memory will have a measurable impact on overall efficiency? I know the PostgreSQL backend might have some of the information in the memory, and that the access mechanisms may use unbelievably efficient techniques (generally speaking), but I think the amount of work required to execute a query and get the data to the requesting program is orders of magnitude more than the overhead involved in a string construction. Notice also that most C++ libraries implement copy-and-write semantics for strings, which means that copying them is almost as inexpensive as returning a char *. > of course the underlying library uses const char *'s anyway. Also of course, > a string is easily constructed from a const char * but the other way needs an > explicit method call. Hmmm... Who are we kidding... If someone is working with C++, they will want string objects anyway; and even if not, they sure will be used to putting the .c_str() if they need it to pass it to atoi/atof, or opening a file, etc. I think it is more what you gain than what you would sacrifice... > I guess this one boils down to how important performance is. Hmmm, I don't know... I get the feeling of premature optimisation here... :-) It's true that we're not talking about something made for a particular application -- we're talking about a library for usage in a wide variety of applications, so efficiency is a must -- but again, my argument is that given that we're talking about accessing fields of databases, the overhead of creating an extra string has to be negligible... (after all, there are fields that are numeric, and the library handles them all as strings... There is an overhead in that, but that's simply the way it works) > One thing I'd > like to do about it in the upcoming version is to provide type-safe access to > the tuples. There'd still be a GetValue() returning const char *, but you > wouldn't need to use it the way you showed in your example, because you'd be > able to read it simply as a native bool. *Now* we're talking! :-) That would be the real hit! I was actually thinking about doing it myself for my personal use... Do you need help with that? :-) (I'm no particular expert with databases, but I do know my way around with C++ :-)) Cheers, Carlos --
On Thu, 17 May 2001, Carlos Moreno wrote: > *Now* we're talking! :-) That would be the real hit! I was > actually thinking about doing it myself for my personal use... > Do you need help with that? :-) (I'm no particular expert > with databases, but I do know my way around with C++ :-)) I'm not getting much work done ATM, being "between machines" as one might say, but one thing I expect I'll be needing help with is simply to find the things in libpq that need to (or need not) be wrapped in libpq++. Jeroen