Search code examples
ibm-midrangejt400jtopen

JTOpen: Writing DDM Files


I'm quite new to work with IBM i (an AS/400). I want to write a DDM File via JTOpen/JT400. Here is what I already did, with the use of the classes inside the jtopenlite.jar from here http://sourceforge.net/projects/jt400/files/JTOpen-full/8.5/

    final String HELLO_WORLD = "Hello World";
    final String LOREM_IPSUM_DOLORES = "lorem ipsum dolores"; 
    String library = "KEKRU1";
    String file = "QRPGLESRC3";
    String member = "DDSTEST2";

    DDMConnection connection = DDMConnection.getConnection("myas400.de", "username", "password");
    DDMRecordFormat recordFormat = connection.getRecordFormat(library, file);

    DDMWriteCallback writeCallback = new DDMWriteCallback() {

        @Override
        public int getRecordDataOffset(DDMCallbackEvent event, int recordIndex) {
            System.out.println(recordIndex);
            return 0;
        }

        @Override
        public byte[] getRecordData(DDMCallbackEvent event, int recordIndex) {              
            byte[] result = new byte[120]; //120 is the ddmfile.getRecordLength()

            byte[] src;
            if (recordIndex == 0){
                src = HELLO_WORLD.getBytes();
            }else{
                src = LOREM_IPSUM_DOLORES.getBytes();
            }

            System.arraycopy(src, 0, result, 0, src.length); //Copy from src to result
            return result;
        }

        @Override
        public int getNumberOfRecords(DDMCallbackEvent event) {
            return 2;
        }

        @Override
        public boolean[] getNullFieldValues(DDMCallbackEvent event, int recordIndex) {
            return null;
        }
    };

    DDMFile ddmFile = connection.open(library, file, member, recordFormat.getName(), DDMFile.WRITE_ONLY, false, 10, 1);

    System.out.println(ddmFile.getRecordLength()); //prints 120     

    connection.write(ddmFile, writeCallback);
    connection.close();

The program enters connection.write(ddmFile, writeCallback); writes the data do the stream and finally arrives at handleReply(file, "ddmS38PUTM", null); (inside connection.write) where it waits for an answer of the Server.

Here's the write method from the Library

public class DDMConnection extends HostServerConnection
{
...

 public void write(DDMFile file, DDMWriteCallback listener) throws IOException
  {
final DDMCallbackEvent event = file.getEventBuffer();
event.setEventType(DDMCallbackEvent.EVENT_WRITE);

int blockingFactor = file.getBatchSize();
int numRecords = listener.getNumberOfRecords(event);
int startingRecordNumber = 0;
int batchSize = numRecords > blockingFactor ? blockingFactor : numRecords;
int id = newCorrelationID();
while (startingRecordNumber < numRecords)
{
  if (startingRecordNumber+batchSize >= numRecords) batchSize = numRecords-startingRecordNumber;
  sendS38PUTMRequest(out_, file.getDCLNAM(), id);
  sendS38BUFRequest(file, out_, id, file.getRecordIncrement(), listener, file.getRecordLength(), startingRecordNumber, batchSize);
  out_.flush();

  handleReply(file, "ddmS38PUTM", null); //here the program waits for the server
  startingRecordNumber += batchSize;
}
}
}

But the Server does not send anything.

Do you have suggestions or another way to write DDM Files?


Solution

  • Perhaps you concerned about whether there is any difference between files created with DDS vs those created with SQL. The system treats them almost identically. Use JDBC on any described physical database file.

    SQL/JDBC does not generally have much ability to work with specific file members. You will need to either

    1) CREATE ALIAS to the specific member, and you would INSERT INTO your alias.

    Or

    2) establish an override in your connection session, probably with the CL command OVRDBF.

    You can execute the SQL statement

    CALL QCMDEXC('OVRDBF QRPGLESRC3 KEKRU1/QRPGLESRC3 TOMBR(DDSTEST2)')
    

    QCMDEXC is a stored procedure that executes CL commands.

    If the file member does not already exist, then you may first need to

    CALL QCMDEXC('ADDPFM  KEKRU1/QRPGLESRC3 DDSTEST2')
    

    If IBM I has not been updated on your system in a while, you may need to add a second parameter for the length of the CL command string, such as 0000000049.00000