Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The code samples below demonstrate how to use the BufferDataSource class. The sample demonstrates the Data Access class of a simple Customer Business Entity that should be filtered on Customer, or an Item Number that was ordered by a customer or the Sales Rep's Name.

Table of Contents

Variable definition

The implementation requires the definition of a class wide private variable. This variable is required to hold a reference to the BufferDataSource instance while FetchData in the DataAccess is executed.

Code Block
languagec#
DEFINE VARIABLE oBufferDataSource AS IBufferDataSource NO-UNDO .

FetchData Implementation

The implementation of the FetchData method uses the QueryParser class to inspect the query string for certain fields. In this case, the QueryParser is used to check if the query string contains the fields eCustomer.ItemNum or eCustomer.RepName. But fields to not exist in the Business Entity temp-table but can still be specified in the query string. When one of the fields if found, an Instance of the BufferDataSource class is created providing the appropriate database tables or BufferSpec instances as a parameter. Providing BufferSpec instances allows to use custom buffer names in the data-source query.

...

Code Block
languagec#
    METHOD OVERRIDE PUBLIC VOID FetchData (poFetchDataRequest AS Consultingwerk.OERA.IFetchDataRequest):
 
        DEFINE VARIABLE oQueryParser     AS QueryParser      NO-UNDO .
        DEFINE VARIABLE oQueryExpression AS IQueryExpression NO-UNDO .
        DEFINE VARIABLE cQueryString     AS CHARACTER        NO-UNDO .
 
        /* Only try to filter by eCustomer.ItemNum or eCustomer.RepName, when eCustomer is the first requested table */
        IF ENTRY (1, THIS-OBJECT:ExpandTables (poFetchDataRequest:Tables)) = "eCustomer":U THEN DO:
 
            cQueryString = ENTRY (1, poFetchDataRequest:Queries, CHR(1)) .
 
            /* Parse QueryString of the request into a list of query predicates */
            oQueryParser = NEW QueryParser () .
            oQueryExpression = oQueryParser:ParseQueryString (cQueryString) .
 
            /* Filter by ItemNum ? */                                          /* In the client query, it's ways filtered relatively to the TT's */
            IF VALID-OBJECT (QueryExpression:FindQueryExpressionForBufferField (BufferHelper:ParseFieldName ("eCustomer.ItemNum":U),
                                                                                oQueryExpression)) THEN
                ASSIGN oBufferDataSource = NEW BufferDataSource ("OrderLine",
                                                                 "Order",
                                                                 "Customer") .
            ELSE
 
            /* Filter by RepName ? */                                          /* In the client query, it's ways filtered relatively to the TT's */
            IF VALID-OBJECT (QueryExpression:FindQueryExpressionForBufferField (BufferHelper:ParseFieldName ("eCustomer.RepName":U),
                                                                                oQueryExpression)) THEN
                ASSIGN oBufferDataSource = NEW BufferDataSource (NEW BufferSpec ("sports2000.SalesRep", "Vertriebler"),
                                                                 NEW BufferSpec ("Customer")) .
        END.
 
        SUPER:FetchData (poFetchDataRequest).
 
        FINALLY:
            GarbageCollectorHelper:DeleteObject(oBufferDataSource) .
        END FINALLY.
    END METHOD.

AttachDataSource Implementation

In the AttachDataSource method we are conditionally replacing the data-source of the temp-table buffer. This is done based on the existence of a valid oBufferDataSource reference. AttachDataSource is executed from within the FetchData method. 

Code Block
languagec#
    METHOD OVERRIDE PROTECTED VOID AttachDataSources ():
 
        DEFINE VARIABLE cMapping AS CHARACTER NO-UNDO.
 
        Consultingwerk.Util.DatasetHelper:SetTrackingChanges (DATASET dsCustomer:HANDLE, FALSE) .
 
        @AttachDataSourcesStart.
        THIS-OBJECT:AttachDataSource (BUFFER eCustomer:HANDLE,
                                      DATA-SOURCE src_Customer:HANDLE, "
                                      CustNum,Customer.CustNum,
                                      Country,Customer.Country,
                                      Name,Customer.Name,
                                      Address,Customer.Address,
                                      Address2,Customer.Address2,
                                      City,Customer.City,
                                      State,Customer.State,
                                      PostalCode,Customer.PostalCode,
                                      Contact,Customer.Contact,
                                      Phone,Customer.Phone,
                                      SalesRep,Customer.SalesRep,
                                      CreditLimit,Customer.CreditLimit,
                                      Balance,Customer.Balance,
                                      Terms,Customer.Terms,
                                      Discount,Customer.Discount,
                                      Comments,Customer.Comments,
                                      Fax,Customer.Fax,
                                      EmailAddress,Customer.EmailAddress":U) .
        @AttachDataSourcesEnd.
 
        /* Replace Data-Source with dynamic one */
 
        IF VALID-OBJECT (oBufferDataSource) THEN DO:
            ASSIGN cMapping = BUFFER eCustomer:DATA-SOURCE-COMPLETE-MAP .
            BUFFER eCustomer:DETACH-DATA-SOURCE () .
            THIS-OBJECT:AttachDataSource(BUFFER eCustomer:HANDLE, oBufferDataSource, cMapping) .
        END.

    END METHOD.

SourceColumn method

At the begin of the SourceColumn method we are now mapping the fields from the alternative database tables (OrderLine, SalesRep):

Code Block
languagec#
        CASE pcColumn:
            WHEN "eCustomer.ItemNum" THEN
                RETURN "OrderLine.ItemNum".
            WHEN "eCustomer.RepName" THEN
                RETURN "SalesRep.Repname" .
        END CASE .

SourceDefaultQuery method

Within SourceDefaultQuery we are now also using the oBufferDataSource variable to test if we are using a custom (dynamic) data-source object handle. The BufferDataSource instance provides a method to return a standard SourceDefaultQuery.

...