[Tip] How to correctly iterate a Record List inside an Extension

[Tip] How to correctly iterate a Record List inside an Extension

  
Hi guys,
 
In the last few months I've been seeing lots of Extensions with incorrect patterns used for iterating Record Lists.
These wrong patterns can produce wrong and unexpected behaviors/results, the most common being missing some entries when doing the iteration.
 
This post shows how to correctly iterate a Record List in an extension.
 
The following code snippet illustrates the correct pattern:
 
 
    try {
                                                                             
        // Call Record List "StartIteration" to ensure the iteration starts from the beginning of the list
        recordList.StartIteration();
                                                                                             
        // Record List "Eof" property indicates if we're in the end of the list
        while (!recordList.Eof) {

            // access "CurrentRec" to retrieve current record information
            string attrName = recordList.CurrentRec.ssSTMyEntity.ssName;
 
            // call "Advance" to move to the next record in the list
            recordList.Advance();
        }
    }  finally {
                                                                           
        // in the finally, call "EndIteration" to indicate that we're no longer iterating the record
        // we must call this function to allow other record list operations, e.g., list-append, list-remove, etc
        recordList.EndIteration();
    }
 
If you are using extensions developed in your company and have actions that use Record Lists, and are having unexpected behavior, you should look into the source code to check if the correct iteration pattern is being used, and fix it if that is the case.
 
If you have any question or comments, please let me know.
 
 
Regards,
João Portela
By the way, the Java code is very similar:

    try {
                                                                             
        // Call Record List "
startIteration" to ensure the iteration starts from the beginning of the list
        recordList.
startIteration();
                                                                                             
        // Record List "Eof" property indicates if we're in the end of the list
        while (!recordList.
isEof()) {

            // access "
currentRec" to retrieve current record information
            string attrName = recordList.
currentRec.ssSTMyEntity.ssName;
 
            // call "
advance" to move to the next record in the list
            recordList.
advance();
        }
    }  finally {
                                                                           
        // in the finally, call "
endIteration" to indicate that we're no longer iterating the record
        // we must call this function to allow other record list operations, e.g., list-append, list-remove, etc
        recordList.
endIteration();
    }


Regards,
Rui Eugénio

Great tip guys. Definitely one to go to the Guides and How Tos forum section.

Regards,

Paulo Tavares
Hello all

And what about in the opposite direction?
Fill a Record List inside an extension and pass it to OS?
Is there an How to?

Antonio
Hi António,

Follows a sample how to insert a record (entity/structure) in a record list, in a extension:


        public void MssExportLists(out RLMyEntityRecordList ssMyEntityList, out RLMyStructureRecordList ssMyStructureList) {
           
            // entity record list creation
            ssMyEntityList = new RLMyEntityRecordList(null);

            // entity record creation
            RCMyEntityRecord ssMyEntityRecord = new RCMyEntityRecord (null);
            ssMyEntityRecord.ssENMyEntity.ssParam1 = "value 1 of entity record";
            //ssMyEntityRecord.ssENMyEntity.ssParam1 = "value 1 of entity record";

            // append entity record to the entity record list
            ssMyEntityList.Append( ssMyEntityRecord);
           
            // structure record list creation
            ssMyStructureList = new RLMyStructureRecordList(null);

            //structure record creation
            RCMyStructureRecord ssMyStructureRecord = new RCMyStructureRecord(null);
            ssMyStructureRecord.ssSTMyStructure.ssParam1 = "value 1 of entity record";
            //ssMyStructureRecord.ssSTMyStructure.ssParam1 = "value 1 of entity record";

            // append structure record to the structure record list
            ssMyStructureList.Append(ssMyStructureRecord);

        } // MssExportLists


Relevant information:
  • when creating a Record object (RC<name>Record), always use the construcutre with null parameter, this constructior performs internal initializations (the constructor without parameter won't do)
  • use the "Append" function of the record list to append a single record
I've also attached a sample extension.

Notice: I've created this extension in Integration Studio 7.00.14 . In other versions/revisions there could be changes in the record/structure/record-lists internal structure.


Regards,
João Portela
Hi João and Rui,
Excellent performance tips..
Share more tips of this kind..:)

Cheers,
Gonçalo Martins
Awesome.
It is working..  :-)
Hi!

Question, do we need to have a structured record to be able to do this? Can't we just use a generic "Record" and "RecordList" instead?

Thanks in advance,
Gino
Hello Gino,

What exactly are you trying to accomplish ?

If you have a generic record (I mean, use the super-class / interface for record and record list) you won't be able to access the data inside the record, so there wouldn't be much use in iterating it ...

Am I missing something here?
To iterate over a record list, I've always used a foreach (.NET), without the startIteration/Eof/Advance as described in the first post (platform 6), and that works fine. Is there any danger by doing so?
@Gino: All record lists are derived from the RecordList class, all records adhere to the IRecord interface. So it would be possible to do some generic processing. However, the things you could do without actually inspecting the data inside are limited (to things like duplicating a list).
Kilian -

In my experience, treating the RecordList as an actual list is hazardous. Things like "not actually iterating all of the rows that were returned by the query" dangerous. This may have changed (and this weekend I was wondering about wrapping it so it worked as expected), but I have learned my lesson in the past and I do not use anything other than the methods described in this thread.

J.Ja
Justin, thanks for the reply. I've luckily never encountered such situations. However, given that RecordList implements IEnumerable, I would think of it as a severe bug if foreach would produce something else than the expected results.
Kilian - I could not agree more. This is a death trap to developers, especially since it seems to work. of the time. I suspect that it is "paging" results from the DB and do long as you only have one page of results it works as expected. I only learned about the issues when code that worked in dev stopped working in production... J.Ja
Hi,
Can anyone explained me of how to save data from recordlist to OS db.
Is there any extension like Recordlist to Entity extension.
Please see my screenshot where i have shown my recordlist.The values from recordlist i need to save in my OS db.
Please respond to me it will be big help for me.
Regards,
ChandrasekarRadhakrishnan
Chandrasekar,

I think this training video might help you out.
In the video they transform an excel file into a record list, and then save the data into multiple database tables.

Next time, post your question on a new thread so that it gets more visibility.