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<numObjects;i++) { + stock[i] = new StockItemStatus(); + stock[i].ref = new StockItemImpl(args,"StockItem"+(i+1)); + orb.connect(stock[i].ref); + } + } catch(org.omg.CORBA.SystemException e) { + e.printStackTrace(); + } + } + + /** + * This method, defined in stock.idl, reserves a slot in the dispenser + */ + public stock.StockItem reserveItem() throws stock.StockException + { + for(int i=0;i<numObjects;i++) { + if(!stock[i].inUse) { + stock[i].inUse = true; + System.out.println("Reserving slot "+i); + return stock[i].ref; + } + } + return null; + } + + /** + * This releases a slot from the dispenser + */ + public void releaseItem(stock.StockItem item) throws stock.StockException + { + for(int i=0;i<numObjects;i++) { + if(stock[i].ref.getInstanceName().equals(item.getInstanceName())) { + stock[i].inUse = false; + System.out.println("Releasing slot "+i); + return; + } + } + System.out.println("Reserved object not a member of this dispenser"); + return; + } + + /** + * This class defines a slot in the dispenser + */ + class StockItemStatus + { + StockItemImpl ref; + boolean inUse; + + StockItemStatus() { + ref = null; + inUse = false; + } + } + +} diff --git a/src/interfaces/jdbc/example/corba/StockItemImpl.java b/src/interfaces/jdbc/example/corba/StockItemImpl.java new file mode 100644 index 0000000000..7f6c5be930 --- /dev/null +++ b/src/interfaces/jdbc/example/corba/StockItemImpl.java @@ -0,0 +1,163 @@ +package example.corba; + +import org.omg.CosNaming.*; + +/** + * This class implements the server side of the example. + * + * $Id: StockItemImpl.java,v 1.1 1999/01/25 21:22:04 scrappy Exp $ + */ +public class StockItemImpl extends stock._StockItemImplBase +{ + private StockDB db; + private String instanceName; + + public StockItemImpl(String[] args,String iname) { + super(); + try { + db =new StockDB(); + db.connect(args[1],args[2],args[3]); + System.out.println("StockDB object "+iname+" created"); + instanceName = iname; + } catch(Exception e) { + e.printStackTrace(); + } + } + + /** + * This is defined in stock.idl + * + * It sets the item to view + */ + public void fetchItem(int id) throws stock.StockException { + try { + db.fetchItem(id); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + + /** + * This is defined in stock.idl + * + * It sets the item to view + */ + public int newItem() throws stock.StockException { + try { + return db.newItem(); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This is defined in stock.idl + * + * It returns the description of a Stock item + */ + public String getDescription() throws stock.StockException { + try { + return db.getDescription(); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This is defined in stock.idl + * + * It returns the description of a Stock item + */ + public int getAvailable() throws stock.StockException { + try { + return db.getAvailable(); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This is defined in stock.idl + * + * It returns the description of a Stock item + */ + public int getOrdered() throws stock.StockException { + try { + return db.getOrdered(); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This is defined in stock.idl + * + * It returns the description of a Stock item + */ + public boolean isItemValid() throws stock.StockException { + try { + return db.isItemValid(); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This is defined in stock.idl + * + * It returns the description of a Stock item + */ + public void addNewStock(int id) throws stock.StockException { + try { + db.addNewStock(id); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This is defined in stock.idl + * + * It returns the description of a Stock item + */ + public void removeStock(int id) throws stock.StockException { + try { + db.removeStock(id); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This is defined in stock.idl + * + * It returns the description of a Stock item + */ + public void orderStock(int id) throws stock.StockException { + try { + db.orderStock(id); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This returns the highest id used, hence the number of items available + */ + public int getLastID() throws stock.StockException { + try { + return db.getLastID(); + } catch(Exception e) { + throw new stock.StockException(e.toString()); + } + } + + /** + * This is used by our Dispenser + */ + public String getInstanceName() { + return instanceName; + } +} + diff --git a/src/interfaces/jdbc/example/corba/StockServer.java b/src/interfaces/jdbc/example/corba/StockServer.java new file mode 100644 index 0000000000..6e34cbcd48 --- /dev/null +++ b/src/interfaces/jdbc/example/corba/StockServer.java @@ -0,0 +1,53 @@ +package example.corba; + +import org.omg.CosNaming.*; + +/** + * This class implements the server side of the example. + * + * $Id: StockServer.java,v 1.1 1999/01/25 21:22:04 scrappy Exp $ + */ +public class StockServer +{ + public static void main(String[] args) + { + int numInstances = 3; + + try { + // Initialise the ORB + org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null); + + // Create the StockDispenser object + StockDispenserImpl dispenser = new StockDispenserImpl(args,"Stock Dispenser",numInstances); + + // Export the new object + orb.connect(dispenser); + + // Get the naming service + org.omg.CORBA.Object nameServiceObj = orb.resolve_initial_references("NameService"); + if(nameServiceObj == null) { + System.err.println("nameServiceObj = null"); + return; + } + + org.omg.CosNaming.NamingContext nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj); + if(nameService == null) { + System.err.println("nameService = null"); + return; + } + + // bind the dispenser into the naming service + NameComponent[] dispenserName = { + new NameComponent("StockDispenser","Stock") + }; + nameService.rebind(dispenserName,dispenser); + + // Now wait forever for the current thread to die + Thread.currentThread().join(); + } catch(Exception e) { + e.printStackTrace(); + } + } +} + + diff --git a/src/interfaces/jdbc/example/corba/readme b/src/interfaces/jdbc/example/corba/readme new file mode 100644 index 0000000000..d44c17613f --- /dev/null +++ b/src/interfaces/jdbc/example/corba/readme @@ -0,0 +1,34 @@ + +The CORBA example is the most complicated of the examples. It +aims to show how to use JDBC & Java2's ORB to access PostgreSQL. + +To compile: + +Type "make corba" to build the example. This will create a new directory +stock which contains the stubs needed by the orb, and all required classes +under the example/corba directory. + +To run: + +NOTE: To run, you will need 3 shells on Win32 (under unix you can get away +with two shells): + +1: Start the naming service + +Unix: tnameserv -ORBInitialPort 1050 & +Win32: tnameserv -ORBInitialPort 1050 + +2: Start the StockServer + + java example.corba.StockServer 3 jdbc:postgresql:dbase user passwd -ORBInitialPort 1050 + +Where: + 3 Number of concurrent sessions to allow + dbase The database (including a hostname if required) + user The PostgreSQL user name + passwd The password + +3: Using a fresh shell, run the client: + + java example.corba.StockClient -ORBInitialPort 1050 + diff --git a/src/interfaces/jdbc/example/corba/stock.idl b/src/interfaces/jdbc/example/corba/stock.idl new file mode 100755 index 0000000000..a25ec78f54 --- /dev/null +++ b/src/interfaces/jdbc/example/corba/stock.idl @@ -0,0 +1,40 @@ +// $Id: stock.idl,v 1.1 1999/01/25 21:22:04 scrappy Exp $ +// +// This is our CORBA bindings for a very simple stock control +// system. +// +// $Id: stock.idl,v 1.1 1999/01/25 21:22:04 scrappy Exp $ +// + +// For some reason, idltojava on my setup doesn't like this to be +// in caps. It could be a problem with Win95 & Samba, but for now, +// this is in lowercase +module stock +{ + exception StockException + { + string reason; + }; + + interface StockItem + { + void fetchItem(in long id) raises (StockException); + long newItem() raises (StockException); + string getDescription() raises (StockException); + long getAvailable() raises (StockException); + long getOrdered() raises (StockException); + boolean isItemValid() raises (StockException); + void addNewStock(in long amount) raises (StockException); + void removeStock(in long amount) raises (StockException); + void orderStock(in long amount) raises (StockException); + long getLastID() raises (StockException); + string getInstanceName(); + }; + + interface StockDispenser + { + StockItem reserveItem() raises (StockException); + void releaseItem(in StockItem item) raises (StockException); + }; + +}; diff --git a/src/interfaces/jdbc/example/corba/stock.sql b/src/interfaces/jdbc/example/corba/stock.sql new file mode 100644 index 0000000000..2b56f9d8e0 --- /dev/null +++ b/src/interfaces/jdbc/example/corba/stock.sql @@ -0,0 +1,27 @@ +-- +-- This creates the database for the stock example +-- $Id: stock.sql,v 1.1 1999/01/25 21:22:04 scrappy Exp $ +-- +drop table stock; + +create table stock ( + id int4, + avail int4, + ordered int4, + valid bool, + description text +); + +create index stock_id on stock(id); + +copy stock from stdin; +1 19 0 t Dell Latitude XPi P133 Laptop +2 3 2 t Iomega Zip Plus drive +3 2 0 f Iomega Ext/Par drive +4 0 4 t Iomega Ext USB drive +5 200 0 t Blank Unbranded CDR media +6 20 30 t Iomega Zip media 100Mb +\. + +grant all on stock to public; +grant all on stock_id to public; diff --git a/src/interfaces/jdbc/postgresql/jdbc1/ResultSetMetaData.java b/src/interfaces/jdbc/postgresql/jdbc1/ResultSetMetaData.java index 95492e81b9..25878dd8c8 100644 --- a/src/interfaces/jdbc/postgresql/jdbc1/ResultSetMetaData.java +++ b/src/interfaces/jdbc/postgresql/jdbc1/ResultSetMetaData.java @@ -6,10 +6,15 @@ package postgresql.jdbc1; // postgresql.jdbc2 package. import java.lang.*; -import java.sql.*; import java.util.*; import postgresql.*; +// We explicitly import classes here as the original line: +//import java.sql.*; +// causes javac to get confused. +import java.sql.SQLException; +import java.sql.Types; + /** * A ResultSetMetaData object can be used to find out about the types and * properties of the columns in a ResultSet diff --git a/src/interfaces/jdbc/postgresql/jdbc2/ResultSet.java b/src/interfaces/jdbc/postgresql/jdbc2/ResultSet.java index 9790dac4aa..54e1081a8e 100644 --- a/src/interfaces/jdbc/postgresql/jdbc2/ResultSet.java +++ b/src/interfaces/jdbc/postgresql/jdbc2/ResultSet.java @@ -789,9 +789,12 @@ public class ResultSet extends postgresql.ResultSet implements java.sql.ResultSe // ** JDBC 2 Extensions ** - public boolean absolute(int row) throws SQLException + public boolean absolute(int index) throws SQLException { - throw postgresql.Driver.notImplemented(); + if (index < 0 || index > 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