From 2ee522954d0d634d520e6f10454a8c63ef004a00 Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" Date: Mon, 25 Jan 1999 21:22:06 +0000 Subject: [PATCH] From: Peter T Mount This implements some of the JDBC2 methods, fixes a bug introduced into the JDBC1 portion of the driver, and introduces a new example, showing how to use the CORBA ORB thats in Java2 with JDBC. The Tar file contains the new files, the diff the changes to the others. CHANGELOG is separate as I forgot to make a .orig ;-) --- src/interfaces/jdbc/CHANGELOG | 9 + src/interfaces/jdbc/Makefile | 42 ++- .../jdbc/example/corba/StockClient.java | 288 ++++++++++++++++++ .../jdbc/example/corba/StockDB.java | 117 +++++++ .../example/corba/StockDispenserImpl.java | 83 +++++ .../jdbc/example/corba/StockItemImpl.java | 163 ++++++++++ .../jdbc/example/corba/StockServer.java | 53 ++++ src/interfaces/jdbc/example/corba/readme | 34 +++ src/interfaces/jdbc/example/corba/stock.idl | 40 +++ src/interfaces/jdbc/example/corba/stock.sql | 27 ++ .../postgresql/jdbc1/ResultSetMetaData.java | 7 +- .../jdbc/postgresql/jdbc2/ResultSet.java | 26 +- 12 files changed, 879 insertions(+), 10 deletions(-) create mode 100644 src/interfaces/jdbc/example/corba/StockClient.java create mode 100644 src/interfaces/jdbc/example/corba/StockDB.java create mode 100644 src/interfaces/jdbc/example/corba/StockDispenserImpl.java create mode 100644 src/interfaces/jdbc/example/corba/StockItemImpl.java create mode 100644 src/interfaces/jdbc/example/corba/StockServer.java create mode 100644 src/interfaces/jdbc/example/corba/readme create mode 100755 src/interfaces/jdbc/example/corba/stock.idl create mode 100644 src/interfaces/jdbc/example/corba/stock.sql diff --git a/src/interfaces/jdbc/CHANGELOG b/src/interfaces/jdbc/CHANGELOG index 2f3dfe2eb2..103c1bf6ff 100644 --- a/src/interfaces/jdbc/CHANGELOG +++ b/src/interfaces/jdbc/CHANGELOG @@ -1,3 +1,12 @@ +Mon Jan 25 19:45:00 GMT 1999 + - created subfolders example/corba and example/corba/idl to hold the + new example showing how to hook CORBA and PostgreSQL via JDBC + - implemented some JDBC2 methods curtesy of Joachim.Gabler@t-online.de + +Sat Jan 23 10:30:00 GMT 1999 + - Changed imports in postgresql.jdbc1.ResultSetMetaData as for some + reason it didn't want to compile under jdk1.1.6 + Tue Dec 29 15:45:00 GMT 1998 - Refreshed the README (which was way out of date) diff --git a/src/interfaces/jdbc/Makefile b/src/interfaces/jdbc/Makefile index 611687dc9a..ab8abc9651 100644 --- a/src/interfaces/jdbc/Makefile +++ b/src/interfaces/jdbc/Makefile @@ -4,16 +4,18 @@ # Makefile for Java JDBC interface # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/Makefile,v 1.11 1999/01/17 04:51:49 momjian Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/Makefile,v 1.12 1999/01/25 21:22:02 scrappy Exp $ # #------------------------------------------------------------------------- FIND = find +IDL2JAVA = idltojava -fno-cpp -fno-tie JAR = jar JAVA = java JAVAC = javac JAVADOC = javadoc RM = rm -f +TOUCH = touch # This defines how to compile a java class .java.class: @@ -44,6 +46,9 @@ all: makeVersion.class @echo ------------------------------------------------------------ @echo To build the examples, type: @echo " make examples" + @echo + @echo "To build the CORBA example (requires Java2):" + @echo " make corba" @echo ------------------------------------------------------------ @echo @@ -142,7 +147,8 @@ clean: $(FIND) . -name "*~" -exec $(RM) {} \; $(FIND) . -name "*.class" -exec $(RM) {} \; $(FIND) . -name "*.html" -exec $(RM) {} \; - $(RM) postgresql.jar + -$(RM) -rf stock example/corba/stock.built + -$(RM) postgresql.jar -$(RM) -rf Package-postgresql *output ####################################################################### @@ -219,7 +225,37 @@ example/blobtest.class: example/blobtest.java example/datestyle.class: example/datestyle.java example/psql.class: example/psql.java example/ImageViewer.class: example/ImageViewer.java -#example/Objects.class: example/Objects.java example/threadsafe.class: example/threadsafe.java example/metadata.class: example/metadata.java + +####################################################################### +# +# CORBA This extensive example shows how to integrate PostgreSQL +# JDBC & CORBA. + +CORBASRC = $(wildcard example/corba/*.java) +CORBAOBJ = $(subst .java,.class,$(CORBASRC)) + +corba: jdbc2 example/corba/stock.built $(CORBAOBJ) + @echo ------------------------------------------------------- + @echo The corba example has been built. Before running, you + @echo will need to read the example/corba/readme file on how + @echo to run the example. + @echo + +# +# This compiles our idl file and the stubs +# +# Note: The idl file is in example/corba, but it builds a directory under +# the current one. For safety, we delete that directory before running +# idltojava +# +example/corba/stock.built: example/corba/stock.idl + -rm -rf stock + $(IDL2JAVA) $< + $(JAVAC) stock/*.java + $(TOUCH) $@ + +# tip: we cant use $(wildcard stock/*.java) in the above rule as a race +# condition occurs, where javac is passed no arguments ####################################################################### diff --git a/src/interfaces/jdbc/example/corba/StockClient.java b/src/interfaces/jdbc/example/corba/StockClient.java new file mode 100644 index 0000000000..7613f886fc --- /dev/null +++ b/src/interfaces/jdbc/example/corba/StockClient.java @@ -0,0 +1,288 @@ +package example.corba; + +import java.io.*; +import java.sql.*; +import org.omg.CosNaming.*; + +/** + * This class is the frontend to our mini CORBA application. + * + * It has no GUI, just a text frontend to keep it simple. + * + * $Id: StockClient.java,v 1.1 1999/01/25 21:22:03 scrappy Exp $ + */ +public class StockClient +{ + org.omg.CosNaming.NamingContext nameService; + + stock.StockDispenser dispenser; + stock.StockItem item; + + BufferedReader in; + + public StockClient(String[] args) { + try { + // We need this for our IO + in = new BufferedReader(new InputStreamReader(System.in)); + + // Initialize the orb + org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null); + + // Get a reference to the Naming Service + org.omg.CORBA.Object nameServiceObj = orb.resolve_initial_references("NameService"); + if(nameServiceObj==null) { + System.err.println("nameServiceObj == null"); + return; + } + + nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj); + if(nameService==null) { + System.err.println("nameService == null"); + return; + } + + // Resolve the dispenser + NameComponent[] dispName = { + new NameComponent("StockDispenser","Stock") + }; + dispenser = stock.StockDispenserHelper.narrow(nameService.resolve(dispName)); + if(dispenser==null) { + System.err.println("dispenser == null"); + return; + } + + // Now run the front end. + run(); + } catch(Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + System.exit(1); + } + } + + public static void main(String[] args) { + new StockClient(args); + } + + public void run() { + // First reserve a StockItem + try { + item = dispenser.reserveItem(); + } catch(Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + System.exit(1); + } + + mainMenu(); + + // finally free the StockItem + try { + dispenser.releaseItem(item); + } catch(Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + System.exit(1); + } + } + + private void mainMenu() { + boolean run=true; + while(run) { + System.out.println("\nCORBA Stock System\n"); + System.out.println(" 1 Display stock item"); + System.out.println(" 2 Remove item from stock"); + System.out.println(" 3 Put item into stock"); + System.out.println(" 4 Order item"); + System.out.println(" 5 Display all items"); + System.out.println(" 0 Exit"); + int i = getMenu("Main",5); + switch(i) + { + case 0: + run=false; + break; + + case 1: + displayItem(); + break; + + case 2: + bookOut(); + break; + + case 3: + bookIn(); + break; + + case 4: + order(0); + break; + + case 5: + displayAll(); + break; + } + } + } + + private void displayItem() { + try { + int id = getMenu("\nStockID to display",item.getLastID()); + if(id>0) { + item.fetchItem(id); + System.out.println("========================================"); + + String status = ""; + if(!item.isItemValid()) + status=" ** Superceded **"; + + int av = item.getAvailable(); + + System.out.println(" Stock ID: "+id+status+ + "\nItems Available: "+av+ + "\nItems on order: "+item.getOrdered()+ + "\n Description: "+item.getDescription()); + System.out.println("========================================"); + + if(av>0) + if(yn("Take this item out of stock?")) { + int rem=1; + if(av>1) + rem=getMenu("How many?",av); + if(rem>0) + item.removeStock(rem); + } + + } + } catch(Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + } + } + + private void bookOut() { + try { + int id = getMenu("\nStockID to take out",item.getLastID()); + if(id>0) { + item.fetchItem(id); + int av = item.getAvailable(); + if(av>0) + if(yn("Take this item out of stock?")) { + int rem=1; + if(av>1) + rem=getMenu("How many?",av); + if(rem>0) + item.removeStock(rem); + } + else { + System.out.println("This item is not in stock."); + int order = item.getOrdered(); + if(order>0) + System.out.println("There are "+item.getOrdered()+" items on order."); + else { + if(item.isItemValid()) { + System.out.println("You will need to order some more "+item.getDescription()); + order(id); + } else + System.out.println("This item is now obsolete"); + } + } + } else + System.out.println(item.getDescription()+"\nThis item is out of stock"); + } catch(Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + } + } + + // book an item into stock + private void bookIn() { + try { + int id = getMenu("\nStockID to book in",item.getLastID()); + item.fetchItem(id); + System.out.println(item.getDescription()); + + if(item.getOrdered()>0) { + int am = getMenu("How many do you want to book in",item.getOrdered()); + if(am>0) + item.addNewStock(am); + } else + System.out.println("You don't have any of this item on ordered"); + + } catch(Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + } + } + + // Order an item + private void order(int id) { + try { + if(id==0) + id = getMenu("\nStockID to order",item.getLastID()); + item.fetchItem(id); + System.out.println(item.getDescription()); + int am = getMenu("How many do you want to order",999); + if(am>0) + item.orderStock(am); + } catch(Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + } + } + + private void displayAll() { + try { + boolean cont=true; + int nr=item.getLastID(); + String header = "\nId\tAvail\tOrdered\tDescription"; + System.out.println(header); + for(int i=1;i<=nr && cont;i++) { + item.fetchItem(i); + System.out.println(""+i+"\t"+item.getAvailable()+"\t"+item.getOrdered()+"\t"+item.getDescription()); + if((i%20)==0) { + if((cont=yn("Continue?"))) + System.out.println(header); + } + } + } catch(Exception e) { + System.out.println(e.toString()); + e.printStackTrace(); + } + } + + private int getMenu(String title,int max) { + int v=-1; + while(v<0 || v>max) { + System.out.print(title); + System.out.print(" [0-"+max+"]: "); + System.out.flush(); + try { + v = Integer.parseInt(in.readLine()); + } catch(Exception nfe) { + v=-1; + } + } + return v; + } + + private boolean yn(String title) { + try { + while(true) { + System.out.print(title); + System.out.flush(); + String s = in.readLine(); + if(s.startsWith("y") || s.startsWith("Y")) + return true; + if(s.startsWith("n") || s.startsWith("N")) + return false; + } + } catch(Exception nfe) { + System.out.println(nfe.toString()); + nfe.printStackTrace(); + System.exit(1); + } + return false; + } +} diff --git a/src/interfaces/jdbc/example/corba/StockDB.java b/src/interfaces/jdbc/example/corba/StockDB.java new file mode 100644 index 0000000000..49ceb1434c --- /dev/null +++ b/src/interfaces/jdbc/example/corba/StockDB.java @@ -0,0 +1,117 @@ +package example.corba; + +import java.sql.*; + +/** + * This class handles the JDBC side of things. It opens a connection to + * the database, and performes queries on that database. + * + * In essence, you could use this class on it's own. The rest of the classes + * in this example handle either the CORBA mechanism, or the frontend. + * + * Note: Before you ask, why perform a query on each call, you have to remember + * that an object could be changed by another client, and we need to ensure that + * the returned data is live and accurate. + * + * $Id: StockDB.java,v 1.1 1999/01/25 21:22:03 scrappy Exp $ + */ +public class StockDB +{ + Connection con; + Statement st; + + // the current stock number + int id = -1; + + public void connect(String url,String usr,String pwd) throws Exception { + Class.forName("postgresql.Driver"); + System.out.println("Connecting to "+url); + con = DriverManager.getConnection(url,usr,pwd); + st = con.createStatement(); + } + + public void closeConnection() throws Exception { + con.close(); + } + + public void fetchItem(int id) throws Exception { + this.id = id; + } + + public int newItem() throws Exception { + // tba + return -1; + } + + public String getDescription() throws SQLException { + ResultSet rs = st.executeQuery("select description from stock where id="+id); + if(rs!=null) { + rs.next(); + String s = rs.getString(1); + rs.close(); + return s; + } + throw new SQLException("No ResultSet"); + } + + public int getAvailable() throws SQLException { + ResultSet rs = st.executeQuery("select avail from stock where id="+id); + if(rs!=null) { + rs.next(); + int v = rs.getInt(1); + rs.close(); + return v; + } + throw new SQLException("No ResultSet"); + } + + public int getOrdered() throws SQLException { + ResultSet rs = st.executeQuery("select ordered from stock where id="+id); + if(rs!=null) { + rs.next(); + int v = rs.getInt(1); + rs.close(); + return v; + } + throw new SQLException("No ResultSet"); + } + + public boolean isItemValid() throws SQLException { + ResultSet rs = st.executeQuery("select valid from stock where id="+id); + if(rs!=null) { + rs.next(); + boolean b = rs.getBoolean(1); + rs.close(); + return b; + } + throw new SQLException("No ResultSet"); + } + + public void addNewStock(int amount) throws SQLException { + st.executeUpdate("update stock set avail=avail+"+amount+ + ", ordered=ordered-"+amount+ + " where id="+id+" and ordered>="+amount); + } + + public void removeStock(int amount) throws SQLException { + st.executeUpdate("update stock set avail=avail-"+amount+ + " where id="+id); + } + + public void orderStock(int amount) throws SQLException { + st.executeUpdate("update stock set ordered=ordered+"+amount+ + " where id="+id); + } + + public int getLastID() throws SQLException { + ResultSet rs = st.executeQuery("select max(id) from stock"); + if(rs!=null) { + rs.next(); + int v = rs.getInt(1); + rs.close(); + return v; + } + throw new SQLException("No ResultSet"); + } + +} diff --git a/src/interfaces/jdbc/example/corba/StockDispenserImpl.java b/src/interfaces/jdbc/example/corba/StockDispenserImpl.java new file mode 100644 index 0000000000..2d961a6dc7 --- /dev/null +++ b/src/interfaces/jdbc/example/corba/StockDispenserImpl.java @@ -0,0 +1,83 @@ +package example.corba; + +import org.omg.CosNaming.*; + +/** + * This class implements the server side of the example. + * + * $Id: StockDispenserImpl.java,v 1.1 1999/01/25 21:22:03 scrappy Exp $ + */ +public class StockDispenserImpl extends stock._StockDispenserImplBase +{ + private int maxObjects = 10; + private int numObjects = 0; + private StockItemStatus[] stock = new StockItemStatus[maxObjects]; + + public StockDispenserImpl(String[] args,String name,int num) + { + super(); + + try { + // get reference to orb + org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null); + + // prestart num objects + if(num>=maxObjects) + num=maxObjects; + numObjects = num; + for(int i=0;i rows.size()) + return false; + this_row = (byte [][])rows.elementAt(index); + return true; } public void afterLast() throws SQLException @@ -816,7 +819,11 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe public boolean first() throws SQLException { - throw postgresql.Driver.notImplemented(); + if (rows.size() <= 0) + return false; + current_row = 0; + this_row = (byte [][])rows.elementAt(current_row); + return true; } public Array getArray(String colName) throws SQLException @@ -941,7 +948,7 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe public int getRow() throws SQLException { - throw postgresql.Driver.notImplemented(); + return current_row; } // This one needs some thought, as not all ResultSets come from a statement @@ -982,7 +989,11 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe public boolean last() throws SQLException { - throw postgresql.Driver.notImplemented(); + if (rows.size() <= 0) + return false; + current_row = rows.size() - 1; + this_row = (byte [][])rows.elementAt(current_row); + return true; } public void moveToCurrentRow() throws SQLException @@ -997,7 +1008,10 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe public boolean previous() throws SQLException { - throw postgresql.Driver.notImplemented(); + if (--current_row < 0) + return false; + this_row = (byte [][])rows.elementAt(current_row); + return true; } public void refreshRow() throws SQLException -- 2.40.0