mtc@PacBell.COM (Mitchell T. Christensen) (12/01/89)
Hi there, We here at Pac*Bell are preparing to delve into Object Oriented production using c++. We have a problem though. I am unable to come up with a clean interface for c++ to our "standardized" DBMS Oracle. Is there anyone out there who has solved this problem? Is there anyone out there who knows of an Object Oriented interface to ANY relational databases? I understand that OODBMS's such as Gemstone would be the ideal solution to this problem but we are limited as to which DB platforms we are "allowed" to use. Thanks in advance. -- /-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\- Mitch Christensen - {ihnp4,dual,lll-crg,qantel,pyramid}!pacbell!pbhyf!mtc /-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-/-\-
horstman@sjsumcs.sjsu.edu (Cay Horstmann) (12/05/89)
In article <6515@pbhyf.PacBell.COM> mtc@PacBell.COM (Mitchell T. Christensen) writes: > > > > Hi there, > > We here at Pac*Bell are preparing to delve into Object Oriented > production using c++. We have a problem though. I am unable to > come up with a clean interface for c++ to our "standardized" DBMS > Oracle. > > Is there anyone out there who has solved this problem? > I'd like to amend this query--does anyone know of some set of classes implementing SQL? One could have a table class and overloaded operators for the relational operations instead of the yucky SQL syntax. Somewhere down the line they should map to embedded SQL queries. Is any such work done anywhere? Cay Horstmann horstman@sjsumcs.sjsu.edu
fst@gtenmc.UUCP (Fariborz "Skip" Tavakkolian) (12/06/89)
In article <1989Dec5.010812.3485@sjsumcs.sjsu.edu> horstman@sjsumcs.SJSU.EDU (Cay Horstmann) writes: >In article <6515@pbhyf.PacBell.COM> mtc@PacBell.COM (Mitchell T. Christensen) writes: >> >> >> Oracle. >> Is there anyone out there who has solved this problem? >> >I'd like to amend this query--does anyone know of some set of classes >implementing SQL? One could have a table class and overloaded operators >for the relational operations instead of the yucky SQL syntax. Somewhere >down the line they should map to embedded SQL queries. Is any such work >done anywhere? >Cay Horstmann >horstman@sjsumcs.sjsu.edu I have been thinking about a nice way to handle this for some time now. I am still using embedded SQL in my C++ routines (I think this is my payment for a past sin). But here are some untried ideas. Say you have something like: class Query { private: . . . public: Query(char* query_statement); ~Query(); prepare(); execute(char* inputfmt, char *outputfmt, ...); ... }; Then you could do this: Query foo("select tabid from systables where tabname = ?"); and then you could invoke Query::prepare() which ``finds out'' (in talking to db-agent or looking up database catalogs) what is expected as input and output (i.e. compiling the query) and setup internal storage for it. Then you could execute the query like so: foo.execute("%s", "%d", "systables", &someintvar); Where the the number of input and output vars would be variable and dependent on the query. My main reason for having an input and output format specifier (a la printf(3), scanf(3)), is the following: A database type DATE may be stored as a "long" internally, but you want to be able to compare it to things like "12/06/89" (i.e. char array), where the internal format does not tell you what the host variable type may be. You could also have a class called QueryCursor where you expect to have a number of retrieved rows: QueryCursor xfoo("cursor_name", "select * from systables"); Then you could either have a QueryCursorIterator class (If that makes sense) or have some member function like: QueryCursor::Fetch(DIRECTION sense, char* outputfmt, ...); (WHERE: enum DIRECTION { NEXT, PREVIOUS, /* or whatever */ } ) One other class you may need is probably the SimpleStatement class for things like update, delete, grant, etc. Hope this helps. -- Fariborz "Skip" Tavakkolian of Automated Cellular Engineering Currently consulting at GTE Telecom, Inc. Mail tiny1!fst@mcgp1 / tiny1!fst@gtenmc / fst@gtenmc
grp@unify.uucp (Greg Pasquariello) (12/07/89)
In article <1989Dec5.010812.3485@sjsumcs.sjsu.edu> horstman@sjsumcs.SJSU.EDU (Cay Horstmann) writes: >In article <6515@pbhyf.PacBell.COM> mtc@PacBell.COM (Mitchell T. Christensen) writes: >> >> >> >> Hi there, >> >> We here at Pac*Bell are preparing to delve into Object Oriented >> production using c++. We have a problem though. I am unable to >> come up with a clean interface for c++ to our "standardized" DBMS >> Oracle. >> >> Is there anyone out there who has solved this problem? >> >I'd like to amend this query--does anyone know of some set of classes >implementing SQL? > >Cay Horstmann >horstman@sjsumcs.sjsu.edu In my previous life with EDS/ATT I began to implement such a set of classes. I don't have them anymore. Are these of general interest? -Greg -- ------------------------------------------------------------------------------- Greg Pasquariello (916) 920-9092 grp@unify.UUCP Unify Corporation ...!{csusac, pyramid}!unify!grp
dsa@dlogics.UUCP (David Angulo) (12/07/89)
In article <1989Dec5.010812.3485@sjsumcs.sjsu.edu>, horstman@sjsumcs.sjsu.edu (Cay Horstmann) writes: > In article <6515@pbhyf.PacBell.COM> mtc@PacBell.COM (Mitchell T. Christensen) writes: > > > > > > > > Hi there, > > > > We here at Pac*Bell are preparing to delve into Object Oriented > > production using c++. We have a problem though. I am unable to > > come up with a clean interface for c++ to our "standardized" DBMS > > Oracle. > > > > Is there anyone out there who has solved this problem? > > > I'd like to amend this query--does anyone know of some set of classes > implementing SQL? One could have a table class and overloaded operators > for the relational operations instead of the yucky SQL syntax. Somewhere > down the line they should map to embedded SQL queries. Is any such work > done anywhere? > You can't really have a set of classes to implement SQL because when you have an embedded SQL statement, you must include the table name and the column name. This is then precompiled into calls to some generic routines. You can (with Oracle) call the generic routines yourself but this is quite cumbersome and subject to change. What we did is to create a code generator that generates a class for each table (actually it generates quite a few things for each table: documentation, the SQL statements to create the table, and the code for the class, etc.). This code has methods for insert, update, fetch, etc. and contains the eSQL statements to do this. We then run the SQL preprocessor and take its outputted code (which it thinks is C) and run it through the C++ compiler. Hope this helps - email me if you want a sample output of the code. S i g h -- David S. Angulo (312) 266-3134 Datalogics Internet: dsa@dlogics.UUCP 441 W. Huron UUCP: ..!uunet!dlogics!dsa Chicago, Il. 60610 FAX: (312) 266-4473
marti@ethz.UUCP (Robert Marti) (12/08/89)
In article <6515@pbhyf.PacBell.COM> mtc@PacBell.COM (Mitchell T. Christensen) writes: > [We are] unable to come up with a clean interface for C++ to our > "standardized" DBMS Oracle. Is there anyone out there who has > solved this problem? Yes, we believe we have solved the problem. About two years ago, we designed a call interface to Oracle for Modula-2 (no flames, please ;-). Although our interface was influenced by Oracle's OCI (formerly known as HLI), we believe that our solution should be portable to other DBMSs which support call interfaces, e.g., Sybase. [As an aside: Oracle's OCI isn't all that bad once you give the procedures sensible names and leave some of the unnecessary parameters away ...] I have recently rewritten this interface in C++. I feel that the concepts of classes, overloading and default parameters all have contributed to make the interface both safer and cleaner than the Modula-2 version from which it was derived. The following class SQL_Request forms the core of our interface: class SQL_Request { public: SQL_Request(const char* statement); // Create a database request which subsequently can be executed // several times with possibly different input parameters by // calling member function Execute. ~SQL_Request(); // Drop the database request. void BindInPar(const char* colName, const char* varAdr, int size, const SQL_NullInd* indAdr = 0); void BindInPar(const char* colName, const int* varAdr, const SQL_NullInd* indAdr = 0); void BindInPar(const char* colName, const double* varAdr, const SQL_NullInd* indAdr = 0); // Bind the program variable at address varAdr as an input parameter // to column colName in the SQL statement associated with this request. // (indAdr may contain the address of a null indicator variable.) void BindOutPar(const char* colName, const char* varAdr, int size, const SQL_NullInd* indAdr = 0); void BindOutPar(const char* colName, const int* varAdr, const SQL_NullInd* indAdr = 0); void BindOutPar(const char* colName, const double* varAdr, const SQL_NullInd* indAdr = 0); // Bind the program variable at address varAdr as an output parameter // to column colName in the SQL statement associated with this request. // (indAdr may contain the address of a null indicator variable.) SQL_Code Execute(); // Execute this request. // Note: Execute copies the values of all bound input parameters // from the program variables into the database columns. SQL_code Fetch(); // Fetch the next row associated with this request. // Note: Fetch copies the values of all bound output parameters // from the database columns into the program variables. private: // ... }; As an illustration, here is a simple example of how to use this interface: #include <stdio.h> #include "SQL.h" int empNo; char empName[20]; double empSal; SQL_NullInd nullSal; SQL_Request query = "SELECT empNo, eName, sal \ FROM Emp \ WHERE sal > :sal"; query.BindInPar("sal", &empSal); query.BindOutPar("empNo", &empNo); query.BindOutPar("eName", empName, sizeof(empName)); query.BindOutPar("sal", &empSal, &nullSal); printf("enter minimum salary: "); scanf(" %f", &empSal); query.Execute(); while (query.Fetch() == SQL_ok) { printf("%4d %s", empNo, empName); if (nullSal == SQL_null) printf(" ** null salary **\n"); else printf(" %f\n", empSal); } I hope this helps ... -- Robert Marti Phone: +41 1 256 52 36 Institut fur Informationssysteme ETH-Zentrum CSNET/ARPA: marti%inf.ethz.ch@relay.cs.net CH-8092 Zurich, Switzerland UUCP: ...uunet!mcvax!ethz!marti
steve@jack.sns.com (J. Steven Harrison) (12/10/89)
In article <6515@pbhyf.PacBell.COM> mtc@PacBell.COM (Mitchell T. Christensen) writes: > We here at Pac*Bell are preparing to delve into Object Oriented > production using c++. We have a problem though. I am unable to > come up with a clean interface for c++ to our "standardized" DBMS > Oracle. > We currently are doing development with Oracle using Pro*C and AT&T's Cfront 2.0. It took some work but we experienced our FCS on Friday and all is well. A couple of hacks to the Pro*C headers put us in business. The hardest part, as it turns out was getting Cfront ported to the Pyramids! Contact me at this address if you have any specific questions. -- ____*_ Dr. J. Steven Harrison {sun,sharkey,pacbell}!indetech!steve \ / / Independence Technologies Director Database Applications \/ / 42705 Lawrence Place FAX: 415 438-2034 \/ Fremont, CA 94538 Voice: 415 438-2011
brad@sqwest.sq.com (Brad Might) (12/13/89)
> You can't really have a set of classes to implement SQL because when you > have an embedded SQL statement, you must include the table name and the > column name. This is then precompiled into calls to some generic routines. You can however send sql statements to Oracle at run-time and have it execute (dynamic sql). You will have to build internal structures based on the information that Oracle returns about the statement - number, type, size of columns You could have an object which receives and holds this info as a buffer between you application and db. DBInterface.sendSQL(SQLStatement); ncols = DBInterface.getNumCols() ; while (DBInterface.getNextRow()){ for (i = 0 ; i < ncols; i++){ switch (DBInterface.colType(i)) { case Chars: printf("%s ", DBInterface.getString(i); break; case Integer: printf("%d ", DBInterface.getInt(i); break ; } } } -- Brad Might brad@sq.com (brad@sq ?) SoftQuad West brad!sq!utzoo!... (604) 585-1999