This directory contains demos with new SQLJ features, most of which are
similar to or derived from JDBC 2.0 functionality.

This file is the README file for sample programs in the SQLJ demo/jdbc20
directory.  It specifies the steps required to run each of the programs
in this directory, and their expected behavior.  All demos use the
scott/tiger schema.

We also provide a makefile for running the samples, which you may be able to
use.  Type 'make' to get usage information.  In this README, we give the
individual steps to run each sample program without using the makefile.

We assume that you have already configured your SQLJ setup, and that you
are able to run the demos in the parent demo directory.

This directory contains demos with new SQLJ features.  Many are derived
from JDBC 2.0 functionality.  Some features (such as support for
java.sql.SQLData) require that you are running in a JDK 1.2 environment,
while all other features are available to you in both, JDK 1.1 and
JDK 1.2 environments, provided you use the Oracle 8.1.7 JDBC drivers.
Finally, many features also work with Oracle 8.1.6 JDBC and -sometimes-
even older Oracle JDBC versions.  For each demo you can find the required
JDK, JDBC, and SQLJ versions.

Finally, two additional demos show new features of Oracle SQLJ that are
not themselves part of the SQLJ ISO standard.


0. First, Set Up Your Environment
*********************************

The programs in the demo directory all use information contained in the 
file "connect.properties" to establish a runtime connection.  If you have
run the tests in the demo directory (parent directory to the current one),
then copy the file connect.properties from demo to demo/jdbc20. Otherwise,
consult demo/README.txt on how to set up connect.properties.


=========================
PART A: SQLJ ISO FEATURES
=========================


1. Sample for Structured Type Support (java.sql.SQLData) 
*********************************************************

JDK support :  JDK 1.2, or higher
JDBC version:  JDBC 8.1.7, or higher
SQLJ version:  SQLJ 8.1.7, or higher; requires runtime12.zip

This example demonstrates sending and receiving instances of structured
SQL types (object types) from the database.
The java.sql.SQLData API in conjunction with type maps, as well as
the oracle.sql.CustomDatum interface are contrasted with one another.

Ensure that you are running in a JDK 1.2 environment.  You must also have
the classes12.zip file from the Oracle 8.1.7 JDBC drivers and the SQLJ
runtime12.zip file, as well as translator.zip in your CLASSPATH.

Then issue the following commands to compile and run this sample:

% sqlplus scott/tiger @StructuredTypes.sql
% sqlj  StructuredTypes.sqlj
% java  StructuredTypes

   Note: If you see the following errors during translation, you need to
   ensure that your environment is set up as outlined above.
   StructuredTypes.sqlj:77.5-77.51: Error: Unsupported Java type for host
   item s (at position #1): StructuredTypes$StructISO.
   StructuredTypes.sqlj:77.5-77.51: Error: Unsupported Java type for host
   item s2 (at position #2): StructuredTypes$StructISO.
   Total 2 errors.

The expected output to the screen is:

*** Establishing Connections
*** Using java.sql.SQLData ***
SELECT * from struct_tab
StructISO: num=1 date=2000-01-01
CALL STRUCT_TY_PROC(StructIso{num=1,date=2000-01-01}, :OUT s2)
   returns s2 = StructIso{num=-998,date=2000-01-01}
*** Using oracle.sql.CustomDatum ***
SELECT * from struct_tab
StructOracle: 1 2000-01-01
CALL STRUCT_TY_PROC(StructOracle: 1 2000-01-01,:OUT so2)
    returns so2 = StructOracle: -998 2000-01-01


Since the SQLData API requires JDBC 2.0, this feature only works in a
JDK 1.2 or higher environment.  Furthermore, since the SQLJ runtime
must implement JDK 1.2-specific APIs (using, for example java.util.Map
for type map objects), the SQLJ runtime12.zip library is mandated.



2. Sample for JDBC 2.0 types (java.sql.Blob, java.sql.Clob, java.sql.Ref) 
*************************************************************************

JDK support :  JDK 1.2, or higher
JDBC support:  JDBC 8.1.7, or higher
SQLJ version:  SQLJ 8.1.7, or higher; requires runtime12.zip

This examples demonstrates sending and receiving instances of different
JDBC 2.0 types, specifically java.sql.Blob, java.sql.Clob, and java.sql.Ref.
This is contrasted with using the corresponding Oracle-specific types
oracle.sql.BLOB, oracle.sql.CLOB, and oracle.sql.REF.

Ensure that you are running in a JDK 1.2 environment.  You must also have
the classes12.zip file from the Oracle 8.1.7 JDBC drivers and the SQLJ
runtime12.zip file, as well as translator.zip in your CLASSPATH.

Issue the following commands to compile and run this sample:

% sqlplus scott/tiger @JDBC20Types.sql
% sqlj  JDBC20Types.sqlj
% java  JDBC20Types

   Note: If you see the following error messages during translation, then
   you are running in a JDK 1.1.x environment. You must use JDK 1.2 or
   later and the JDBC library classes12.zip.
   JDBC20Types.sqlj:18.3-19.73: Error: Type java.sql.Blob for column b is
   not a valid Java type.
   JDBC20Types.sqlj:18.3-19.73: Error: Type java.sql.Clob for column c is
   not a valid Java type.
   JDBC20Types.sqlj:44.5: Error: Class java.sql.Ref not found.
   Total 3 errors.
 
The expected output to the screen is:

*** Demo of JDBC 2.0 types
SELECT of BLOB and CLOB columns
#2  BLOB=null CLOB="" 
#8  BLOB=[] CLOB=null 
#9  BLOB=[] CLOB="" 
SELECT of REF columns
REF=[basetype "SCOTT.JDBC20_TY"] 
REF=[basetype "SCOTT.JDBC20_TY"] 
REF=null 
REF=[basetype "SCOTT.JDBC20_TY"] 
*** Demo of corrsponding Oracle types
SELECT of BLOB and CLOB columns
#2  BLOB=null CLOB="" 
#8  BLOB=[] CLOB=null 
#9  BLOB=[] CLOB="" 
SELECT of REF columns
REF=[basetype "SCOTT.JDBC20_TY"] value is {2,null,CLOB="" }
REF=[basetype "SCOTT.JDBC20_TY"] value is {9,BLOB=[] ,CLOB="" }
REF=null 
REF=[basetype "SCOTT.JDBC20_TY"] value is {8,BLOB=[] ,null}


NOTE 1: You can also compile this example in a JDK 1.2 environment
using runtime.zip.  In this case, the code that is generated for
the java.sql.Xxxx types is not compliant with the SQLJ ISO
specification, but the program will run using the Oracle SQLJ runtime.

NOTE 2: Translation with runtime12.zip will require runtime12.zip
for running your application.



3. Sample for Scrollable Iterators 
**********************************

JDK support :  JDK 1.1, or 1.2
JDBC support:  JDBC 8.1.6 and 8.1.7
SQLJ version:  SQLJ 8.1.7, or higher

This examples demonstrates scrollable iterators. It shows both, named
scrollable iterators, and positional scrollable iterators.

The following commands will compile and run this sample:

% sqlj  ScrollableIterator.sqlj
% java  ScrollableIterator

Expected output to the screen is:

*** Demo of scrollable named iterator
BeforeFirst.
First. Name: SMITH #7369
Name: ALLEN #7499
First. Name: SMITH #7369
Last. Name: MILLER #7934
First. Name: SMITH #7369
Name: SCOTT #7788
Name: BLAKE #7698
AfterLast.
*** Demo of scrollable positional iterator
BeforeFirst.
First. Name: SMITH #7369
Name: ALLEN #7499
First. Name: SMITH #7369
Last. Name: MILLER #7934
First. Name: SMITH #7369
Name: SCOTT #7788
Name: BLAKE #7698
AfterLast.


Note that scrollable iterators are supported in JDK versions 1.2 as well
as 1.1 and in conjunction with Oracle JDBC version 8.1.6 or higher.



4. Sample for DataSource support
********************************

JDK support :  JDK 1.1 or 1.2  plus javax.naming.* and javax.sql.* packages
JDBC support:  JDBC 8.1.6 and 8.1.7
SQLJ version:  SQLJ 8.1.7, or higher


This example demonstrates the use of DataSources in connection contexts to
establish database connections.  For testing purposes we provide a rather
simple-minded implementation of a context factory in DataSourceCF.
This class can be used to create an InitialContext with JDBC data sources.
(We gave DataSourceCF a .sqlj extension so that it will not get inadvertently
removed alongside with generated .java files.)

Ensure that you are running in an environment where the javax.naming and
javax.sql packages are available. You could either use JDK 1.3 or add
the j2ee.jar from the JDK Standard Extensions to your CLASSPATH.
You should be able to find the following classes, for example:
   javap javax.sql.DataSource
   javap javax.naming.Context

As always, you need the zip file from the Oracle JDBC driver and the SQLJ
translator.zip, as well as one of the runtime zips in your CLASSPATH.

The following commands will compile and run this sample (note that the
initial context provider is identified in the java.naming.factory.initial
property):

% sqlj DataSource.sqlj DataSourceCF.sqlj
% java -Djava.naming.factory.initial=DataSourceCF DataSource


The expected output to the screen is:

DataSourceCF.SimpleDataSource("jdbc/defaultDataSource").getConnection()
jdbc/defaultDataSource: Employee #7788 is named SCOTT and makes 3000.0.
DataSourceCF.SimpleDataSource("jdbc/test").getConnection()
jdbc/test: Employee #7369 is named SMITH and makes 800.0.
DataSourceCF.SimpleDataSource("jdbc/test").getConnection("scott")
scott@jdbc/test: Employee #7934 is named MILLER and makes 1300.0.


Note that DataSources are supported in JDK versions 1.2 and 1.1 as well
as as in Oracle JDBC 8.1.6, or higher.  In addition, the javax.naming
and javax.sql packages, as well as an initial context provider are required.



5. Sample for connection pooling interoperability
*************************************************

JDK support :  JDK 1.1 or 1.2  plus javax.naming.* package
JDBC support:  JDBC 8.1.6 or 8.1.7
SQLJ version:  SQLJ 8.1.7, or higher


This example shows how SQLJ connection contexts can be built on top
of a connection cache, such as the one provided with Oracle JDBC versions
8.1.6 and up.

Ensure that you are running in an environment where the javax.naming 
package is available. You could either use JDK 1.3, or add the j2ee.jar
from the JDK Standard Extensions to your CLASSPATH.
You do need to be able to find the following classes from javax.naming:
   javap javax.naming.Referenceable
   javap javax.naming.NamingException

As always, you should have the zip file from the Oracle JDBC driver and the
SQLJ translator.zip, as well as one of the runtime zips in your CLASSPATH.

The following commands will compile and run this sample:

% sqlj  ConnectionCache.sqlj
% java  ConnectionCache


Expected output to the screen is:

*** DYNAMIC_SCHEME demo
Creating 5 contexts...
DefaultContext 0 succeeded.
DefaultContext 1 succeeded.
DefaultContext 2 succeeded.
DefaultContext 3 succeeded.
DefaultContext 4 succeeded.
Active size: 5
Cache Size : 5
Contexts   :  ctx[0]=open   ctx[1]=open   ctx[2]=open   ctx[3]=open   ctx[4]=open  
Closing three contexts...
Active size: 2
Cache Size : 3
Contexts   :  ctx[0]=closed ctx[1]=closed ctx[2]=closed ctx[3]=open   ctx[4]=open  
Closing the DataSource...
Active size: 0
Cache Size : 0
Contexts   :  ctx[0]=closed ctx[1]=closed ctx[2]=closed ctx[3]=open   ctx[4]=open  
*** FIXED_RETURN_NULL_SCHEME demo
Creating 5 contexts...
DefaultContext 0 succeeded.
DefaultContext 1 succeeded.
DefaultContext 2 succeeded.
DefaultContext 3 failed: java.sql.SQLException: null connection.
DefaultContext 4 failed: java.sql.SQLException: null connection.
Active size: 3
Cache Size : 3
Contexts   :  ctx[0]=open   ctx[1]=open   ctx[2]=open   ctx[3]=null   ctx[4]=null  
Closing two contexts...
Active size: 1
Cache Size : 3
Contexts   :  ctx[0]=closed ctx[1]=closed ctx[2]=open   ctx[3]=null   ctx[4]=null  
Closing the DataSource...
Active size: 0
Cache Size : 0
Contexts   :  ctx[0]=closed ctx[1]=closed ctx[2]=open   ctx[3]=null   ctx[4]=null  


NOTE: This example does not work with SQLJ 8.1.5 or 8.1.6.  However,
you may be able to obtain patches for these older SQLJ versions to
support interoperability with pooled connections from:

   http://technet.oracle.com/



6. Sample for fetch size support
********************************

JDK support :  JDK 1.1 or 1.2
JDBC support:  any Oracle JDBC driver
SQLJ version:  SQLJ 8.1.7 or higher

This example shows how to set the fetch size for queries on the
SQLJ ExecutionContext and demonstrated the effects on roundtrip
performance.

The following commands will compile and run this sample:

% sqlj  FetchSize.sqlj
% java  FetchSize

Expected output to the screen is:

*** Demo of setFetchSize(), getFetchSize()
Using fetch size 1: X.XX seconds
Using fetch size 5: X.XX seconds
Using fetch size 20: X.XX seconds


The actual numbers X.XX that you see will depend on your platform
and database configuration.  In general you will see better
performance with larger fetch sizes - up to a certain point.

NOTE: You may prefer the standard setFetchSize() API that is shown
here over the Oracle-specific OracleConnection.setDefaultRowPrefetch()
method that is illustrated in PrefetchDemo.sqlj (in the demo parent
directory).



7. Sample for batching support
******************************

JDK support : JDK 1.1 or 1.2
JDBC support: any Oracle JDBC driver
SQLJ version: SQLJ 8.1.6, 8.1.7, or higher

This demo is already available in the parent directory of the jdbc20 directory.
It is assumed that you have modified the connect.properties file in
the parent directory appropriately.

The following commands will compile and run this sample:

% cd ..
% sqlplus scott/tiger @BatchDemo.sql
% sqlj  BatchDemo.sqlj
% java  BatchDemo

Expected output to the screen is:

*** Batch Demo ***
Connected.
>>> Inserting 100 records <<<<
Inserting one record at a time. Done in X.XXX seconds.
Inserting in batch of 10. Done in X.XXX seconds.
Inserting in batch of 100. Done in X.XXX seconds.
Inserting in batch of 1000. Done in X.XXX seconds.
>>> Inserting 1000 records <<<<
Inserting one record at a time. Done in X.XXX seconds.
Inserting in batch of 10. Done in X.XXX seconds.
Inserting in batch of 100. Done in X.XXX seconds.
Inserting in batch of 1000. Done in X.XXX seconds.
*** End of Demo ***

The actual numbers X.XXX that you see will depend on your platform
and database configuration.  You should see better performance with
higher batch size values.  However, you will also notice diminishing
returns, or even performance loss as the batch size is increased.
Note also that the BATCH_DEMO table may not be representative to a
typical table that might be used in your application.

Change back into the jdbc20 directory before running the remaining demos.



============================
PART B: ORACLE SQLJ FEATURES
============================


9. Sample: converting JDBC result sets to SQLJ positional iterators
*******************************************************************

JDK support :  JDK 1.1 or 1.2
JDBC support:  any Oracle JDBC driver
SQLJ version:  SQLJ 8.1.7 or higher

This example shows the use of FETCH CURRENT FROM ... INTO ...
syntax for positional iterators.  This syntax simplifies
migration from JDBC to SQLJ code.

The following commands will compile and run this sample:

% sqlj  JDBCConversion.sqlj
% java  JDBCConversion

Expected output to the screen is:

*** Issuing query with JDBC code
SCOTT does make more than the manager JONES (3000.0 vs. 2975.0)
FORD does make more than the manager JONES (3000.0 vs. 2975.0)
ALLEN does not make more than the manager BLAKE (1600.0 vs. 2850.0)
WARD does not make more than the manager BLAKE (1250.0 vs. 2850.0)
JAMES does not make more than the manager BLAKE (950.0 vs. 2850.0)
TURNER does not make more than the manager BLAKE (1500.0 vs. 2850.0)
MARTIN does not make more than the manager BLAKE (1250.0 vs. 2850.0)
MILLER does not make more than the manager CLARK (1300.0 vs. 2450.0)
ADAMS does not make more than the manager SCOTT (1100.0 vs. 3000.0)
JONES does not make more than the manager KING (2975.0 vs. 5000.0)
CLARK does not make more than the manager KING (2450.0 vs. 5000.0)
BLAKE does not make more than the manager KING (2850.0 vs. 5000.0)
SMITH does not make more than the manager FORD (800.0 vs. 3000.0)
*** Issuing query with SQLJ code
SCOTT does make more than the manager JONES (3000.0 vs. 2975.0)
FORD does make more than the manager JONES (3000.0 vs. 2975.0)
ALLEN does not make more than the manager BLAKE (1600.0 vs. 2850.0)
WARD does not make more than the manager BLAKE (1250.0 vs. 2850.0)
JAMES does not make more than the manager BLAKE (950.0 vs. 2850.0)
TURNER does not make more than the manager BLAKE (1500.0 vs. 2850.0)
MARTIN does not make more than the manager BLAKE (1250.0 vs. 2850.0)
MILLER does not make more than the manager CLARK (1300.0 vs. 2450.0)
ADAMS does not make more than the manager SCOTT (1100.0 vs. 3000.0)
JONES does not make more than the manager KING (2975.0 vs. 5000.0)
CLARK does not make more than the manager KING (2450.0 vs. 5000.0)
BLAKE does not make more than the manager KING (2850.0 vs. 5000.0)
SMITH does not make more than the manager FORD (800.0 vs. 3000.0)


10. Sample for Java serialization support
*****************************************

JDK support :  JDK 1.1 or 1.2
JDBC support:  any Oracle JDBC driver
SQLJ version:  SQLJ 8.1.7 or higher

This examples demonstrates transparent serialization of Java classes
into RAW or BLOB columns.  This feature uses functionality very similar
to the type map properties as defined in the SQLJ ISO standard.

The following commands will compile and run this sample:

% sqlplus  scott/tiger @JavaSerialization
(you will have to exit the sqlplus script)

% sqlj  JavaSerialization.sqlj
% java  JavaSerialization


Expected output to the screen is:

Inserting serialized Java objects
Retrieving serialized Java objects
#0  AnObject{0,zero}  AnotherObject{0}
#1  AnObject{1,un}  AnotherObject{1}
#2  AnObject{2,zwei}  AnotherObject{4}
#3  AnObject{3,tres}  AnotherObject{9}

NOTE: Only the OCI version of the Oracle 8.1.6 or higher JDBC driver
supports storing serializable Java objects directly into BLOB columns.
The thin and server-side (kprb) drivers do not currently support this
functionality.

No changes should be committed to the database, since autocommit is false
for the connection established through the Oracle.connect() call, and
a ROLLBACK is issued before closing the connection.
