cancel
Showing results for 
Search instead for 
Did you mean: 

Generic OData $query_options to ABAP SQL mappers available ?

Former Member
0 Kudos

Hello OData ABAP experts,

as described e.g. in implementing a "basic" CL*DPC_EXT class is straight foreward. Also we do not use RFC or BOR stuff to be OData'fied, so we are free to design code within the DPC_EXT itself.

To have "full" support, we like to implement as much as possible OData language like $filter,$orderby,$select and other URI options natively map them most efficient & generic to ABAP SQL.

As as result, we like to code in *_GET_ENTITYSET method something like:


SELECT (lv_columns)

UP TO lv_mrows ROWS

FROM (lv_table)

     INTO TABLE et_entityset

WHERE (lv_where)

ORDER BY (lv_order_by).

Unfortunately the interface for *_GET_ENTITY or *_GET_ENTITYSET is different e.g. io_tech_request_context->GET_OSQL_WHERE_CLAUSE( ) works in entityset but not in entity due to different tech_request_contexts.

The thing is how to obtain the lv_* values in a correct,generic and complete (support all OData features) way out of the SEGW generated interface...

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method XXX_GET_ENTITYSET
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_ENTITY_NAME                           TYPE        STRING
* | [--->] IV_ENTITY_SET_NAME                  TYPE        STRING
* | [--->] IV_SOURCE_NAME                         TYPE        STRING
* | [--->] IT_FILTER_SELECT_OPTIONS       TYPE        /IWBEP/T_MGW_SELECT_OPTION
* | [--->] IS_PAGING                                          TYPE        /IWBEP/S_MGW_PAGING
* | [--->] IT_KEY_TAB                                         TYPE        /IWBEP/T_MGW_NAME_VALUE_PAIR
* | [--->] IT_NAVIGATION_PATH                      TYPE        /IWBEP/T_MGW_NAVIGATION_PATH
* | [--->] IT_ORDER                                           TYPE        /IWBEP/T_MGW_SORTING_ORDER
* | [--->] IV_FILTER_STRING                              TYPE        STRING
* | [--->] IV_SEARCH_STRING                         TYPE        STRING
* | [--->] IO_TECH_REQUEST_CONTEXT        TYPE REF TO /IWBEP/IF_MGW_REQ_ENTITYSET(optional)
* | [<---] ET_ENTITYSET                                      TYPE        XXX=>TT_XXX
* | [<---] ES_RESPONSE_CONTEXT                 TYPE        /IWBEP/IF_MGW_APPL_SRV_RUNTIME=>TY_S_MGW_RESPONSE_CONTEXT
* | [!CX!] /IWBEP/CX_MGW_BUSI_EXCEPTION
* | [!CX!] /IWBEP/CX_MGW_TECH_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>

After searching usages of OData by SAP code itself I'm little bit disappointed. Every CL*DPC*EXT* code handles the *DPC* interface in a differenty way.

Is there a ABAP based best practice guideline (besides Creating High-Quality OData Services - SAP Gateway Foundation (SAP_GWFND) - SAP Library ) or generic classes (like io_tech_request_contect in and all lv_* parts out) to fulfill these "always the same" *DPC* to ABAP SQL mapping ?

What is your experience here ?

Thanks in advance,

Matthias

Accepted Solutions (0)

Answers (1)

Answers (1)

former_member184867
Active Contributor
0 Kudos

All "Technical Request Context" parameters in DPC methods are designed with respect to the context of the HTTP operation under consideration .

The context and expectation of a QUERY operation is different than the context and expectation of a READ operation. Same is true for CREATE,UPDATE and DELETE. "Technical Request Context" contains operation specific information and that's why they are of different type even though the name is same in all the methods.

Now 'io_tech_request_context->GET_OSQL_WHERE_CLAUSE( )' is meant to give you the SQL representation of ' $filter ' options, which only makes sense for Query operation. Even we have one more API to perform filter related work (io_tech_request_context->GET_FILTER). 

But as $filter is only valid for QUERY scenarios, we have the relevant Method(s) only in the tech request context of GET_ENTITYSET.

On the other side , read is always on the keys. It will not be very difficult to construct the SQL filter string using the tech request context  available via  GET_ENTITY method.

Refer to method GET_CONVERTED_SOURCE_KEYS of the tech request context  available via  GET_ENTITY method.  With some ABAP code we shall be able to construct the SQL where clause.

Former Member
0 Kudos

Hello Atanu,

thanks for your explanations. Indeed, the context for READ/QUERY is different, so it's logical to have different interfaces. But technically a READ is also only a QUERY with given primary key.

So the ABAP in GET_ENTITYSET is:

DATA(lv_where) = io_tech_request_context->get_osql_where_clause_convert( ).
SELECT * FROM ztab
        UP TO @lv_max_index ROWS
     INTO CORRESPONDING FIELDS OF TABLE @et_entityset
WHERE (lv_where)

  ORDER BY PRIMARY KEY.


The GET_ENTITY is:

DATA: ls_tab_key type ztab.
io_tech_request_context->get_converted_keys( IMPORTING es_key_values = ls_tab_key ).
SELECT SINGLE * FROM ztab
      INTO @er_entity
WHERE key = @ls_tab_key-key.


Two things seems not nice

  • the get_osql_where_clause_convert( ) would work fine also in GET_ENTITY
    (e.g. with one WHERE clause generated out of the keys like key EQ 'value').
  • the INTO ... is a row at READ and a table at QUERY
    (a READ could also return a table just with zero or one row it in)

For me, a READ is only a subset (a restricted variant) of a QUERY, but unfortunately not in the DPC interface and not in the implementation. We wrote own code that GET_ENTITY calls GET_ENTITYSET to reflect that.


Best regards,

Matthias