Read by Position
Reading data by position is a good mean in order to position the property on a certain position. For iterating through a collection, one should use rather next() and previous(), since get() will throw an exception, when the instance required is not available. Moreover, next() and previous() evaluate filter conditions and automatically skip instances that do not fulfill the filter condition.
The position of an instance in a collection depends on the sort order for the collection. When a sort order has been selected (setAccessKey()), instances are always provided according to this sort order.
Selecting instance by position is possible in different ways:
- reading instance at absolute position
- reading instance at relative position
- scrolling forward or backward
The simplest one is calling get() with a set position (first instance always has position 0). The get() function selects the instance at requested position and returns the property with the selected instance. When the function does not succeed an exception is thrown.
There are two special functions in order to read the first and the last instance (first() and last()), which allow accessing the first and the last instance in a collection. Reading the first or last instance can also be achieved by calling toTop() and then calling next() orprevious().
Since the get() function returns the property with the selected instance, you may immediately access instance information.
Sometimes you may need to relocate the instance when terminating the function in order to restore the original state of the property handle. Therefore, you may store the position of the currently selected instance calling currentIndex() as in the example below. This is the only way restoring the selection by position, when a filter condition has been set.
Selecting an instance at absolute position becomes critical, when a filter condition has been set for the property (collection). In this case, it is a better way referring to relative position.
... fragment ( Property &persons ) {
int current = persons.currentIndex();
// print PID of first person
printf(persons.first(true).value("pid").toString());
// print PID of last person
printf(persons.last(true).value("pid").toString());
// read last instance using previous()
persons.top();
persons.previous(); // last instance
// relocate instance
// should be the sam if nothing has changed in the collection
persons.get(current);
}
In order to read an instance by position from a collection with filter condition, getRelative() function is more appropriate. The getRelative() function returns the first instance fulfilling the filter condition.
Calling getRelative() function is sometimes critical, since you cannot trust the position returned from the relativeIndex() function. The relative index is used for access optimization and usually differs when reading a collection backward or forward. Thus, getRelative() is good for locating a starting point, but not for relocating an instance. In order to reselect an instance, you should always use get().
... fragment ( Property &persons ) {
int current = persons.currentIndex();
persons.setFilter("age >= 18");
// print PID of first accepted person
printf(persons.getRealtive(0).value("pid").toString());
// read last accepted instance
persons.toTop();
persons.previous(); // last instance
// print PID of last accepted person
printf(persons.value("pid").toString());
// reset filter and relocate instance
persons.setFilter("");
persons.get(current);
}
Scrolling through a collection is typical way for reading all or a number of subsequent instances from a collection. Usually, instances are selected one by one, in which case previous() and next() functions are the most appropriate. Since previous and next do skip instances not fulfilling a filter condition, those functions work well for filtered and for unfiltered collections.
previous() and next() return false at end of collection. When calling previous() and next() for an unselected property handle, next() locates the first instance while previous() locates the last one. In order to deselect a collection properly, you may call the top() or cancel() function.
In order to go a number of instances forward or backward, you may call the position() function. position() scrolls forward in a collection the number of instances passed in count by skipping instances, which do not fulfill filter conditions.
In order to go backward in the collection, a negative value must be passed to the function. Thus, position(1) does the same as next() and position(-1) does the same as previous(). The difference is, that position() returns a property and throws an exception when not being successful, while next() and previous() return false at end of collection.
Usually, previous() and next() do not read but locate the instance in the property handle, only. In order to select the instance locates immediately, previous() and next() as well as first() and last() my get a read option, in which case an instance is selected when the functions return true.
... :: function ( Property &persons ) {
persons.toTop();
while ( persons.next(true) ) // locate next and read
printf(persons.value("pid").toString()); // same as persons.get(0);
}