In the Presentation Layer, developers create (and modify) queries against a Model. This allows the client (UI, usually the Presenter or View) to filter, sort and otherwise manipulate the data contained in the Model without necessarily having an impact on how that data was populated. This separation of queries (and data) is an important element of the OERA. It is also necessary for the client to be able to pass query definitions from the client to the server in order to populate the client data set.
The reference components provide a mechanism for this in two parts: a query definition mechanism, which allows for the storage of the query definition, and a query manipulation mechanism.
The QueryDefinition object contains meta-data about a single query: buffers, joins (between those buffers), filters (non-buffer), sorting and the like. It allows the use of named buffers. The QueryDefinition does not perform any operations on the query itself (such as open, close or reposition); these actions are left to the Query object.
This object exists mainly because having an object allows us to extend or modify the kinds of data associated with a query without having to change any of the parameters. This is similar to the intent of using EventArgs. We can also change the implementation of the (say) buffers without any external changes (to use objects instead of strings, for instance).
The QueryDefinition object implements the IQueryDefinition interface. The QueryDefinition class and IQueryDefinition interface can be found in the OpenEdge.Core.System package.
The QueryDefinition object implements OpenEdge.Base.Interfaces.ISerializable, and so can be serialized to and from a LONGCHAR, which can be passed across session boundaries (ie an AppServer) if need be.
The IQueryDefinition object defines a single event to allow objects that use it to react to any changes in the definition.
Query and IQuery
The Query object contains a single QueryDefinition object, which it uses to define the query. The Query object creates and operates on an ABL query. The Query object has a number of properties that are restricted to having a PUBLIC GET, and a restricted set (protected or private accessors). These properties are either derived from the ABL query or are set via the constructor (or derived therein).
The Query methods are mostly wrappers around corresponding ABL query methods. The following lists some more specialized Query methods:
The Query object has two constructors.
Query Result Row Identification
Rows in a query can be uniquely identified by means of a Row Key Array, as described here.
The fact that the CurrentRowKey array order is defined by the actual buffer order in the query makes the key volatile. The buffer order of a query can change. It is thus not unlikely that there are cases that uses the key to reposition that might allow the buffer orders to change after the get and before the reposition. The key is currently used to set position for an appending batch, but in that case the buffer order cannot change between the requests.
One solution to this problem is to flatten the RowKey into a single character field. This can be done without loosing any information by adding table qualifiers to the field references. The drawback is that some parsing is required, but it is consistent with how field references are managed elsewhere, for example in databinding where qualifed fields are used when the query/resultlist have multiple buffers.
The ITableOwner interface is implemented by the class that defines a table handle from which to create buffers for the query.
Hi Peter,I compared the documentation with the current (1.0.3) implementation of the IQueryDefinition and IQuery interface classes. In the Classview there is a method in the IQuery class called ReopenQuery (void) but in code there are Reopen methods with a LOGICAL return-value. Might be a little confusing while reading the documentation. Kind regards,Marko
We haven't been good with keeping our UML diagrams in sync with the code. The AutoDox2 doc might be more useful for inspecting classes but is of course not hugely useful for examining the relationships between them. Getting (and keeping) the doc up-to-date is an important part of this project but we've not got there quite yet, sorry.