Strong-typed Query Support

Introduction

The OERA-backend of the SmartComponent Library supports CCSBE01 compliant strong-typed queries through the Consultingwerk.OERA.Ccs.QueryDefinition class. The Consultingwerk.OERA.QueryBuilder.TableQuery class simplifies the creation of array based IQueryDefinition instances. The Business Entity Designer plugin TableQueryBuilderGeneratorPlugin can be used to generate specific TableQuery instances for individual Business Entity Designer Tables.

Using the TableQueryBuilderGeneratorPlugin

When the TableQueryBuilderGeneratorPlugin is activated in the Business Entity Designer configuration, the plugin will generate strong-typed query classes whenever a Business Entity is generated or re-generated.

Defining queries

Strong typed queries are defined as independent object instances.

DEFINE VARIABLE oQuery AS CustomerQuery NO-UNDO .

oQuery = NEW CustomerQuery() .

Similar to the filter constructors of the DatasetModel classes, the strong-typed query classes provide constructors that initialize a query based on the fields of indexes with the "Default Search-Code Generation" flag turned on.

Defining query selections

The table query instance (e.g. CustomerQuery) contains references to factories for predicates for the fields of the table. The factories are type-safe and do only provide access to the query operators supported for the data type of the field. 

Multiple query predicates can be combined using logical operators (AND, OR).

oQuery = NEW CustomerQuery() .

oQuery:Country:Eq("USA"):And:City:Begins("Bost"):And:CreditLimit:Ge(100000) .

MESSAGE oQuery:ToQueryString(TRUE)
    VIEW-AS ALERT-BOX.

Defining nested queries

In contrast to the DatasetModel filter classes, the Table Query classes support nested queries. Nested queries will be executed using brackets in the query string. Nested queries are defined using multiple table query instances which will be joined in an outer table query instance:

oQuery = NEW CustomerQuery() .

oQuery:Or (NEW CustomerQuery ():Country:Eq("USA"):And:City:Begins("Bost"),
           NEW CustomerQuery ():Country:Eq("DE"):And:City:Begins("Colog")).

MESSAGE oQuery:ToQueryString(TRUE)
    VIEW-AS ALERT-BOX.

Nested queries can be combined with query predicates attached to the outer table query instance:

oQuery = NEW CustomerQuery() .

oQuery:Or (NEW CustomerQuery ():Country:Eq("USA"):And:City:Begins("Bost"),
           NEW CustomerQuery ():Country:Eq("DE"):And:City:Begins("Colog"))
       :And:CreditLimit:Lt(1000).

MESSAGE oQuery:ToQueryString(TRUE)
    VIEW-AS ALERT-BOX.

Using the TableQuery instances

The TableQuery instances (e.g. CustomerQuery) are not executing any query or data access themselves. Rather they can be used to parameterize various other data access selections.

Retrieving a Query String

The samples above have already demonstrated the ToQueryString() method of the TableQuery class. The method expects a logical argument which specifies of the query string should reference the query fields including the table name or abbreviated without the table name. 

oQuery = NEW CustomerQuery() .

oQuery:Or (NEW CustomerQuery ():Country:Eq("USA"):And:City:Begins("Bost"),
           NEW CustomerQuery ():Country:Eq("DE"):And:City:Begins("Colog"))
       :And:CreditLimit:Lt(1000).

MESSAGE oQuery:ToQueryString(FALSE)
    VIEW-AS ALERT-BOX.

Using the TableQuery to formulate a FetchDataRequest

The TableQuery (e.g. CustomerQuery) can be used to formulate a FetchDataRequest used to retrieve data through the Service Interface or Service Adapter or the Business Entity FetchData method.

DEFINE VARIABLE oQuery   AS CustomerQuery     NO-UNDO .
DEFINE VARIABLE oRequest AS IFetchDataRequest NO-UNDO .

{Consultingwerk/SmartComponentsDemo/OERA/Sports2000/dsCustomer.i}

oQuery = NEW CustomerQuery() .

oQuery:Or (NEW CustomerQuery ():Country:Eq("USA"):And:City:Begins("Bost"),
           NEW CustomerQuery ():Country:Eq("DE"):And:City:Begins("Colog"))
       :And:CreditLimit:Lt(1000).

oRequest = NEW FetchDataRequest ("eCustomer",
                                 oQuery:ToQueryString(TRUE),
                                 0) .

ServiceInterface:FetchData ("Consultingwerk.SmartComponentsDemo.OERA.Sports2000.CustomerBusinessEntity",
                            oRequest,
                            OUTPUT DATASET dsCustomer) .

FOR EACH eCustomer:
    DISPLAY CustNum Country City CreditLimit .
END.

Retrieving a CCS QueryDefinition instance

The TableQuery (e.g. CustomerQuery) can be used to formulate a CCS GetDatainstance used to retrieve data through the CCSBE interfaces.

USING Ccs.BusinessLogic.*                                  FROM PROPATH.
USING Ccs.Common.* 	                                       FROM PROPATH.
USING Consultingwerk.Framework.*                           FROM PROPATH.
USING Consultingwerk.OERA.*                                FROM PROPATH.
USING Consultingwerk.OERA.Ccs.*                            FROM PROPATH.
USING Consultingwerk.SmartComponentsDemo.OERA.Model.*      FROM PROPATH.
USING Consultingwerk.SmartComponentsDemo.OERA.Sports2000.* FROM PROPATH.

USING Consultingwerk.Util.* FROM PROPATH.

DEFINE VARIABLE oQuery   AS CustomerQuery                     NO-UNDO .
DEFINE VARIABLE oRequest AS IGetDataRequest                   NO-UNDO .
DEFINE VARIABLE oEntity  AS Ccs.BusinessLogic.IBusinessEntity NO-UNDO .

{Consultingwerk/SmartComponentsDemo/OERA/Sports2000/dsCustomer.i}

/* Simulate CCS Framework Bootstrap */
Ccs.Common.Application:ServiceManager = NEW CcsServiceManager() .

oQuery = NEW CustomerQuery() .

oQuery:Or (NEW CustomerQuery ():Country:Eq("USA"):And:City:Begins("Bost"),
           NEW CustomerQuery ():Country:Eq("DE"):And:City:Begins("Colog"))
       :And:CreditLimit:Lt(1000).

oRequest = NEW GetDataRequest(NEW GetDataTableRequest("eCustomer",
                                                      oQuery:ToQueryEntry(),
                                                      0)) .

oEntity = CAST (Ccs.Common.Application:ServiceManager:getService(GET-CLASS (CustomerBusinessEntity)),
                Ccs.BusinessLogic.IBusinessEntity) .

oEntity:getData (oRequest,
                 OUTPUT DATASET dsCustomer) .

FOR EACH eCustomer:
    DISPLAY CustNum Country City CreditLimit .
END.