Dear mates,
Here is the next part of my blog related to OS functionality. You can find the beginning here:
Persistent classes: revival of a spirit. Query by range.
I presented the way how we can use local variables as more transparent way to create a query request.
As a result of IF_OS_CA_PERSISTENCY~GET_PERSISTENT_BY_QUERY method we have a table of OSREFTAB type.
So let's first consider how SAP proposes to process such references in DEMO_QUERY_SERVICE example:
LOOP AT connections ASSIGNING FIELD-SYMBOL(<connection>).
connection = CAST #( <connection> ).
result-carrid = connection->get_carrid( ).
result-connid = connection->get_connid( ).
APPEND result TO results.
ENDLOOP.
That's probably OK - but let's assume we have really pretty big number of attributes. The idea of numerous get_() method calls each time i want to read the full object structure didn't make me happy. I'm too lazy for it.
In my background there were several tasks when I used asXML serialization-deserialization and i decided to try it here:
The logic should be very simple:
When I tried to serialize CL_SPFLI_PERSISTENT instance i got nothing interesting:
<asx:abap version="1.0" xmlns:asx="http://www.sap.com/abapxml">
<asx:values>
<STRUC href="#o52"/>
</asx:values>
<asx:heap xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:abap="http://www.sap.com/abapxml/types/built-in" xmlns:cls="http://www.sap.com/abapxml/classe//www.sap.com/abapxml/types/dictionary">
<cls:CL_SPFLI_PERSISTENT id="o52"/>
</asx:heap>
</asx:abap>
The reason of such a short file is that object must have IF_SERIALIZABLE_OBJECT interface to be serialized.
As I was going to use it for my own object I just created new Z class for SPFLI table but with this interface defined.
This time the result looked rather better:
<asx:abap version="1.0" xmlns:asx="http://www.sap.com/abapxml">
<asx:values>
<STRUC href="#o52"/>
</asx:values>
<asx:heap xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:abap="http://www.sap.com/abapxml/types/built-in" xmlns:cls="http://www.sap.com/abapxml/classes/global" xmlns:dic="http://www.sap.com/abapxml/types/dictionary">
<cls:ZCL_SPFLI_PERSISTENT id="o52">
<ZCL_SPFLI_PERSISTENT>
<CARRID>UA</CARRID>
<CONNID>3517</CONNID>
<COUNTRYFR>DE</COUNTRYFR>
<CITYFROM>FRANKFURT</CITYFROM>
<AIRPFROM>FRA</AIRPFROM>
<COUNTRYTO>US</COUNTRYTO>
<CITYTO>NEW YORK</CITYTO>
<AIRPTO>JFK</AIRPTO>
<FLTIME>495</FLTIME>
<DEPTIME>10:40:00</DEPTIME>
<ARRTIME>12:55:00</ARRTIME>
<DISTANCE>6162.0</DISTANCE>
<DISTID>KM</DISTID>
<FLTYPE/>
<PERIOD>0</PERIOD>
</ZCL_SPFLI_PERSISTENT>
</cls:ZCL_SPFLI_PERSISTENT>
</asx:heap>
</asx:abap>
2. Well, now we need to think how we can fill SPFLI structure from XML. To see which file should I have I serialized SPFLI structure first:
<asx:abap version="1.0" xmlns:asx="http://www.sap.com/abapxml">
<asx:values>
<STRUC>
<MANDT/>
<CARRID>UA</CARRID>
<CONNID>3517</CONNID>
<COUNTRYFR>DE</COUNTRYFR>
<CITYFROM>FRANKFURT</CITYFROM>
<AIRPFROM>FRA</AIRPFROM>
<COUNTRYTO>US</COUNTRYTO>
<CITYTO>NEW YORK</CITYTO>
<AIRPTO>JFK</AIRPTO>
<FLTIME>495</FLTIME>
<DEPTIME>10:40:00</DEPTIME>
<ARRTIME>12:55:00</ARRTIME>
<DISTANCE>6162.0</DISTANCE>
<DISTID>KM</DISTID>
<FLTYPE/>
<PERIOD>0</PERIOD>
</STRUC>
</asx:values>
</asx:abap>
lns:dic
3. Now we have asXML with object instance from one side, and we have asXML that we need to create .
There are several ways how to create it:
As I'm lazy i chose the last one. I'm not a big expert in XSLT so this is what actually I managed to create:
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sap="http://www.sap.com/sapxsl"
>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<asx:abap
version="1.0"
xmlns:asx="http://www.sap.com/abapxml">
<asx:values>
<STRUCT>
<xsl:copy-of select="./*/*/*/*/*"/>
</STRUCT>
</asx:values>
</asx:abap>
</xsl:template>
</xsl:transform>
To my big surprise it worked:
So what I did I provided a new method for this operation:
class-methods TO_DATA
importing
!IO_OBJECT type ref to IF_SERIALIZABLE_OBJECT
changing
!CS_DATA type ANY .
method TO_DATA.
try.
" Object to asXml:serializable object
call transformation id
source struc = io_object
result xml data(lv_xml).
" asXml:serializable object to asXml:data
call transformation zcw_obj2struc
source xml lv_xml
result xml data(lv_xml_struc).
" asXml:data to data
call transformation id
source xml lv_xml_struc
result struct = cs_data.
catch cx_transformation_error into data(lo_cx).
if 1 eq 2.
" here you can go from the debugger
data(lo_output) = cl_demo_output=>new( ). " <-place the cursor here and press Shift+F12
lo_output->begin_section( 'Object to asXml:serializable object' ).
lo_output->write_xml( xml = lv_xml ).
lo_output->begin_section( 'asXml:serializable object to asXml:data' ).
lo_output->write_xml( xml = lv_xml_struc ).
lo_output->write_text( lo_cx->get_text( ) ).
lo_output->display( ).
endif.
endtry.
endmethod.
and finally this SAP code:
agent = ca_spfli_persistent=>agent.
TRY.
query_manager = cl_os_system=>get_query_manager( ).
query = query_manager->create_query(
i_filter = `AIRPFROM = PAR1 AND AIRPTO = PAR2` ).
connections =
agent->if_os_ca_persistency~get_persistent_by_query(
i_query = query
i_par1 = airpfrom
i_par2 = airpto ).
LOOP AT connections ASSIGNING FIELD-SYMBOL(<connection>).
connection = CAST #( <connection> ).
result-carrid = connection->get_carrid( ).
result-connid = connection->get_connid( ).
APPEND result TO results.
ENDLOOP.
cl_demo_output=>display( results ).
CATCH cx_root INTO exc.
cl_demo_output=>display( exc->get_text( ) ).
ENDTRY.
became more elegant to me:
types: begin of query_ts,
airpfrom type spfli-airpfrom,
airpto type spfli-airpto,
end of query_ts.
data: lt_results type table of spfli.
zcl_os_api=>select_by_query(
exporting
io_agent = zca_spfli_persistent=>agent " Class-Specific Persistence Interface
is_selection = value query_ts(
airpfrom = p_from
airpto = p_to
)
importing
et_data = lt_results
).
You probably think that such a technique will decrease overall performance sufficiently but that was a big surpsrise to me that trasnformation works really fast.
Also I think that XSLT transformation can be optimized somehow but here we need experts in this area to recieve an advise.
Will be glad to see your comments here. Critics is appreciated.
Petr.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
6 | |
5 | |
3 | |
2 | |
2 | |
2 | |
2 | |
2 | |
2 | |
2 |