Writing DL/I calls to access an IMS database with the IMS Universal JDBC driver

In addition to support for SQL queries, the IMS Universal JDBC driver also supports casts to DL/I objects.

The IMS Universal JDBC driver is normally used to provide an interface for an application program to make SQL queries to get IMS data. However, you can also cast to DL/I objects from the JDBC interface. You might want to use this approach if you want to reuse a known-good DL/I call in a new application context, or if you want to obtain maximum performance for a simple query.

Procedure

  1. Create JDBC and PSB connection objects.
  2. Obtain a connection to the IMS data.
  3. Cast the JDBC connection to get a PSB handle from the IMS Universal DL/I driver.
  4. Get a PCB object from your existing PSB connection object.
  5. Allocate a data connection from your PSB object.
  6. Build and submit your segment search argument (SSA) list.
  7. Create Path and PathSet objects to contain the returned data.
  8. Process the PathSet data.

This example demonstrates how to make the cast to the DL/I driver and obtain data. This examples accesses a JDBC connection from a JNDI datasource that was created in a JEE server with the IMS Universal Database Resource Adapter.

import java.sql.Connection;

import javax.naming.InitialContext;
import javax.sql.DataSource;

import com.ibm.ims.dli.PCB;
import com.ibm.ims.dli.PSB;
import com.ibm.ims.dli.Path;
import com.ibm.ims.dli.PathSet;
import com.ibm.ims.dli.SSAList;



public class JDBCToDLI {
	public static void main(String args[]){
		
		Connection conn = null; // This is a JDBC Connection
		// This is the equivalent connection object to the JDBC connection for the IMS Java DL/I API
		PSB psb = null; 		
		try{
			// Lookup the JNDI DataSource that contains the IMS connection information. 
			// The JNDI DataSource would be defined in the JEE 
			// server with the IMS Universal Database Resource Adapters
			InitialContext ic = new InitialContext();
			DataSource ds = (DataSource) ic.lookup("myJNDIName");
			
			// Get a JDBC Connection from the DataSource
			conn = ds.getConnection();
			
			// Cast the JDBC Connection to the IMS ConnectImpl in order to retrieve 
			// a handle to the PSB in the IMS Java DL/I API
			psb = ((com.ibm.ims.jdbc.ConnectionImpl) conn).getPSB();
			

			//Get a PCB using the PSB you just created
			PCB ivp1pcb = psb.getPCB("PHONEAP");
			//Allocate PSB1 to establish a connection to the data
			psb.allocate();
			System.out.println("PSB for IVPDB1 Allocated");
			
			//Do work on PSB1
			SSAList ssaList = ivp1pcb.getSSAList("PhoneBook");	//Create an SSA list to use in a DLI call.
										//This SSA list qualifies the entire 
										//PhoneBook segment. PhoneBook is an
										//alias name for segment A1111111 which
										//is specificed in the database view 
										//(DFSIVPDBView.java).

			//Create a path object for later use
			Path path = null;
			PathSet ps = ivp1pcb.batchRetrieve(ssaList);		//This statement uses the PCB object created
										//above to do a batch retrieval of 
										//all the segment instances of PhoneBook.
										//The data returned will be placed in
										//a PathSet which is a collection of
										//Path's containing the data you requested
			System.out.println("Batch retrieved all segment instances of Phone Book");
			
			System.out.println("FIRSTNAME\tLASTNAME\tEXTENSION\tZIPCODE");
			System.out.println("------------------------------------------------------------------");
			
			/*
			* The following while loop process the PathSet by checking that there is
			* a next element (ps.hasNext), then it prints out the three fields that are defined in the
			* database view (FIRSTNAME, LASTNAME, EXTENSION) for segment PhoneBook. This will continue
			* until  there are no more elements in the PathSet
			*/
			while(ps.hasNext()){
				path = ps.next();
				System.out.println(path.getString("FIRSTNAME").trim()+"\t\t"+
				path.getString("LASTNAME").trim()+"\t\t"+
				path.getString("EXTENSION").trim()+"\t"+
				path.getString("ZIPCODE").trim());
			}
				
		    //INSERT a segment into the PhoneBook
		    path = ssaList.getPathForInsert("PhoneBook");
		    path.setString("LASTNAME", "LAST15");
		    path.setString("FIRSTNAME", "FIRST15");
		    path.setString("EXTENSION", "8-111-1515");
		    path.setString("ZIPCODE", "D15/R15");
		    ivp1pcb.insert(path, ssaList);
		    System.out.println("\nInserted New Phone Book Entry with LASTNAME equal to LAST15");
		    
		    //Batch retrieve all segment instances of the PhoneBook (A1111111) segment
		    ps = ivp1pcb.batchRetrieve(ssaList);
		    System.out.println("\nBatch Retrieved all segment instances of Phone Book and verify LAST15 was inserted");
		    
		    System.out.println("FIRSTNAME\tLASTNAME\tEXTENSION\tZIPCODE");
		    System.out.println("------------------------------------------------------------------");
		    while(ps.hasNext()){
		    	path = ps.next();
		    	System.out.println(path.getString("FIRSTNAME").trim()+"\t\t"+
    			path.getString("LASTNAME").trim()+"\t\t"+
    			path.getString("EXTENSION").trim()+"\t"+
    			path.getString("ZIPCODE").trim());
		    }
		    
		    //UPDATE FIRSTNAME to NEWNAME where LASTNAME equals LAST15
		    ssaList.addInitialQualification(1, "LASTNAME", SSAList.EQUALS, "LAST15");
		    if(ivp1pcb.getUnique(path, ssaList, true)){
		    	path.setString("FIRSTNAME", "NEWNAME");
		    	if(16448==ivp1pcb.replace(path)){
		    		System.out.println("\nUpdated FIRSTNAME for segments with LASTNAME of LAST15");
		    	}
		    }
		    
		    ssaList.removeAllQualificationStatements(1);
		    //Batch retrieve all segment instances of the PhoneBook (A1111111) segment
		    ps = ivp1pcb.batchRetrieve(ssaList);
		    System.out.println("\nBatch Retrieved all segment instances of Phone Book and " +
		    		"\nverify that the FISTNAME was updated for the entry LAST15");
		    
		    System.out.println("FIRSTNAME\tLASTNAME\tEXTENSION\tZIPCODE");
		    System.out.println("------------------------------------------------------------------");
		    while(ps.hasNext()){
		    	path = ps.next();
		    	System.out.println(path.getString("FIRSTNAME").trim()+"\t\t"+
    			path.getString("LASTNAME").trim()+"\t\t"+
    			path.getString("EXTENSION").trim()+"\t"+
    			path.getString("ZIPCODE").trim());
		    }
		    
		    //DELETE all segments where LASTNAME equals LAST15
		    ssaList.addInitialQualification(1, "LASTNAME", SSAList.EQUALS, "LAST15");
		    if(ivp1pcb.batchDelete(ssaList)==1){
		    	System.out.println("\nSegment with LASTNAME equal to LAST15 has been deleted");
		    }
		    
		    ssaList.removeAllQualificationStatements(1);
		    
		    //Batch retrieve all segment instances of the PhoneBook (A1111111) segment
		    ps = ivp1pcb.batchRetrieve(ssaList);
		    System.out.println("\nBatch Retrieved all segment instances of Phone Book and " +
		    		"\nverify that the segment with LASTNAME of LAST15 has been deleted");
		    
		    System.out.println("FIRSTNAME\tLASTNAME\tEXTENSION\tZIPCODE");
		    System.out.println("------------------------------------------------------------------");
		    while(ps.hasNext()){
		    	path = ps.next();
		    	System.out.println(path.getString("FIRSTNAME").trim()+"\t\t"+
    			path.getString("LASTNAME").trim()+"\t\t"+
    			path.getString("EXTENSION").trim()+"\t"+
    			path.getString("ZIPCODE").trim());
		    }
		    
		    //Commit the work
		    psb.commit();
		    System.out.println("\nPSB Committed");
		    //Deallocate the PSB
		    psb.deallocate();
		    System.out.println("PSB deallocated");
		    //Close the socket connection
		    psb.close();
		    System.out.println("Connection Closed");
		    System.out.println("Open Database IVP Completed");
		} catch(Exception e) {
			e.printStackTrace();
			try {
			    psb.deallocate();
			    psb.close();
			}catch(Exception e1){
				e1.printStackTrace();
			}
		}
	}
}