Skip to main content

%Iterator.Global

Class to iterate over a global buffering results internally

Marked [hidden] as this is for internal use only at this point while it is under development.

From https://usconfluence.iscinternal.com/display/SQL/Global+Iterator+Interface+in+COS

Usage: Set iterator=##Class(Iterator.Global).%New(global,depth,flags,start,end)
While iterator.getNext(.data,.sub1,.sub2) {
    ; Do something with data,sub1,sub2
}

The arguments to the constructor are:

Flags bit values are:
   1 - If set, we do not want the data value returned (no variable is supplied in the GetNext() call)
   2 - If set, start range is exclusive (if false, start range is inclusive).
   4 - If set, end range is exclusive (if false, end range is inclusive).
   8 - If set, big strings are cached with the data block as space permits.


An alternate design pattern is to create an iterator with %New() and then set it up for an operation with Init(). The arguments to Init() are the same as %New().

Method Inventory

Methods

final method Init(baseGREF As %String, depth As %Integer, flags As %Integer, start As %String, end As %String) as %Integer [ Language = cpp ]
rc = Init(global,depth,flags,start,end)

Used with an existing %Iterator.Global object (created by a %New(), %New()(depth) or %New()(<args>)) to start a new operation. Any unreturned results from the prior operation are lost. If a block of code wants to run multiple iterations, using the Init() method on an existing object is faster than destroying the object and building a new one as it avoids the overhead of object creation. Otherwise the two coding patterns are the same.

Returns zero if there are no results for this operation (eg. the 1st call to .getNext() would return zero)

The arguments to the constructor are:
global - $name(^global("X")) which provides the root node we will be iterating below.
depth - Number of subscripts we will iterate over, so 1 for a single level $order equivalent loop, 2 means we will iterate over two levels etc.
flags - Bit mask with meaning listed below. Defaults to '0'.
start - Optional start value to iterate from, this is always the first subscript below the 'global' name provided, so we can only restrict the initial subscript.
end - Optional end value to iterate to.

Flags bit values are:
   1 - If set, GetNext() will not be passed a return data value argument
   2 - If set, start range is exclusive (if false, start range is inclusive).
   4 - If set, end range is exclusive (if false, end range is inclusive).

Returns:
   0 - There are no answers, the next getNext() will return failure
   1 - There is one or more answer(s) available


final method getNext() as %Integer [ Language = cpp ]
rc=getNext([.dataval,][.sub1, .sub2,...,.subn] fetches the next result in the sequence. If the data value is being returned (controlled by the flags argument to the constructor), then its value is returned in the 1st variable passed by reference to this method. The max # of subargs passed (by value) is based on the depth argument in the constructor. The return value indicates whether the end has been reached.

If the subscript argument list is shorter than the depth value, the "trailing" subscript values which do not have return variables are not returned. The dataval and all subscript args can be omitted if one is simply interested in iterating over a list to count the number of entries.

Returns:
   0 - no more data, did not return a result. If a data is being returned, the passed variable is set to the null string, the subscript value arguments are not modified.
   >0 - returned a result. The data argument contains the data value from the global reference (if requested by flags) and the subscript values are returned in the individual subargs variables. The value returned is the number of subscripts which have new values since the last .getNext() call. For instance, 1 means the last subscript has changed, 2 means the last 2 subscripts have changed, etc.
final method getzu113Cookie() as %CPP.LongLong [ Language = cpp ]
$ZU(113,<magicCookie>, <getNext args...>) is an alternate interface to the .getNext() functionality.

The cookie returned here is passed unchanged as the 1st argument to $ZU(113) and then the rest of the arguments are exactly the same as what would be passed to the .getNext() method.

The value returned from $ZU(113) is the same 0/>0 (failure/success) that .getNext returns along with the optional data value and the various subscript values passed by reference.
final method setSkip(levelCount As %Integer) as %Integer [ Language = cpp ]
setSkip() affects the execution of the next .getNext() call.
Returns:
     0 - failure, <level count> out of range (<0 or >=subscript depth)
     1 - success

<level count> is the number of subscript levels we want to skip over. This means that we back up to the next "result" at the next higher subscript level and resume from there. setSkip(1) means skip the rest of the results at the lowest subsript level, setSkip(2) would be one level above that, etc. The largest value of <level count> is the # of iteration levels minus one. Negative values and values which are too large are ignored and generate a return code of 0 (as described above).

setSkip() cannot be called until at least one result has been returned from getNext() or an exception is generated. This is considered an error as a different starting point could have been specified.

for instance if we are iterating with a depth of 3 (returning 3 subscript levels) over data which looks like
^data(1,1,1)=111
^data(1,1,2)=112
^data(1,1,3)=113
^data(1,1,4)=114
^data(1,2,2)=122
^data(1,2,3)=123
^data(1,2,4)=124
^data(2,1,1)=211
^data(2,1,2)=212
and .getIter(.dataval,.sub1,.sub2,.sub3) just returned ^data(1,1,3). After calling .setSkip(1) the next getNext() call will return ^data(1,2,2). At this point after calling .setSkip(2) the next .getNext() would return ^data(2,1,1).

Inherited Members

Inherited Methods

FeedbackOpens in a new tab