When to log objects into DB?
Applications get bigger and bigger due to the evolving changes in requirements.
Scenario: You are working on a project where users enter data through screens and
you probably do BAPI/BADI calls or BDC calls.
Application holds very valuable data, sensitive.
You need to save each data as possible.
Logging is one way of doing this.
You can log the data into tables...
Business Scenario: This is a real world exampleç lets say you are working on a project where
users can be able to create many acct documents at a time, depending on the data users enter.
So you need to save each data, screen data, the internal tables, etc....
Lets say user has entered all the screen data and lots of business calculations behind the scene occur.
Smth went wrong during the process we need to see every data thats been entered
Murphys Law things that can go wrong will definetely go wrong.
How to Approach?
Foundation: Object oriented world we should be living inso we need to answer all these questions in OO world.
Approach: we will need to wrap all the data in objects from the screen data to the data that we will need to analyze.
Lets say screen data is wrapped up as a z class which hold many details of the screen as well as the internal tales.
How to store object into DB?
How can we store object into the DB, we need a way to map object to a data type.
The possible way is storing the object as raw data of course eg rawstring.
How to convert objects into raw data
Of course the answer lies at the Serilazibility and the transformation of the object
IF_SERIALIZABLE_OBJECT is the interface that needs to be implemented!!
**transform the object
CALL TRANSFORMATION ID_INDENT
SOURCE OBJ = IO_OBJECT ( has to be serializable)
RESULT XML LT_RESTAB.
Then we can convert much easily ...:)
Here the Transformation
Sample code for the Transformation:
class ZCL_GENERAL definition
public
create public .
*"* public components of class ZCL_GENERAL
*"* do not include other source files here!!!
public section.
class-methods TRANSFORM_OBJECT_TO_RAWSTRING
importing
!IO_OBJECT type ref to IF_SERIALIZABLE_OBJECT
returning
value(RV_XSTRING) type XSTRING
exceptions
TRANSFORMATION_FAILED .
class-methods TRANSFORM_RAWSTRING_TO_OBJECT
importing
value(IV_XSTRING) type XSTRING
exporting
!EO_OBJECT type ref to IF_SERIALIZABLE_OBJECT
exceptions
TRANSFORMATION_FAILED .
endclass.
Implementation
Transformatıon Sample Code: Notice that there is also compression applied!!
METHOD TRANSFORM_OBJECT_TO_RAWSTRING.
types:
line_t(4096) type x .
types:
table_t type standard table of line_t .
DATA:LT_RESTAB TYPE table_t.
FIELD-SYMBOLS: <LFS_RESTAB> LIKE LINE OF LT_RESTAB.
CALL TRANSFORMATION ID_INDENT
SOURCE OBJ = IO_OBJECT
RESULT XML LT_RESTAB.
IF LT_RESTAB IS NOT INITIAL.
LOOP AT LT_RESTAB ASSIGNING <LFS_RESTAB>.
CONCATENATE RV_XSTRING <LFS_RESTAB>
INTO RV_XSTRING IN BYTE MODE.
ENDLOOP.
**compresss here
TRY.
CALL METHOD CL_ABAP_GZIP=>COMPRESS_BINARY
EXPORTING
RAW_IN = RV_XSTRING
IMPORTING
GZIP_OUT = RV_XSTRING.
CATCH CX_PARAMETER_INVALID_RANGE .
CATCH CX_SY_BUFFER_OVERFLOW .
CATCH CX_SY_COMPRESSION_ERROR .
ENDTRY.
ELSE.
RAISE TRANSFORMATION_FAILED.
ENDIF.
ENDMETHOD.
We transformed the object into raw data!!
Now we need to recover the data back tooo from rawstring back to the object we saved!!
How to Recover
Notice that we use compression to save more data!!!
METHOD TRANSFORM_RAWSTRING_TO_OBJECT.
DATA: LV_XSTRING_DECOMPRESSED TYPE XSTRING.
***Restore the object here
****first decompress the object
*now decompress
CL_ABAP_GZIP=>DECOMPRESS_BINARY(
EXPORTING
GZIP_IN = IV_XSTRING
IMPORTING
RAW_OUT = LV_XSTRING_DECOMPRESSED
).
" revert TRANSFORMATION
CALL TRANSFORMATION ID_INDENT
SOURCE XML LV_XSTRING_DECOMPRESSED
RESULT OBJ = EO_OBJECT.
IF NOT EO_OBJECT IS BOUND.
RAISE TRANSFORMATION_FAILED.
ENDIF.
ENDMETHOD.
Testing the Transformation
Here is a sample code to test the transformation!!!
METHOD TEST_TRANSFORM.
DATA: LO_OBJECT TYPE REF TO ZCL_TEST,
LO_OBJECT_RECOVERED TYPE REF TO ZCL_TEST,
LO_OBJECT_SERILIAZABLE TYPE REF TO IF_SERIALIZABLE_OBJECT,
LV_XSTRING_COMPRESSED TYPE XSTRING
.
CREATE OBJECT LO_OBJECT.
LV_XSTRING_COMPRESSED =
ZCL_AKSA_GENERAL=>TRANSFORM_OBJECT_TO_RAWSTRING(
IO_OBJECT = LO_OBJECT
).
ZCL_AKSA_GENERAL=>TRANSFORM_RAWSTRING_TO_OBJECT(
EXPORTING
IV_XSTRING = LV_XSTRING_COMPRESSED
IMPORTING
EO_OBJECT = LO_OBJECT_SERILIAZABLE
EXCEPTIONS
TRANSFORMATION_FAILED = 1
).
IF SY-SUBRC <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
***type cast
LO_OBJECT_RECOVERED ?= LO_OBJECT_SERILIAZABLE.
* CL_AUNIT_ASSERT=>ASSERT_EQUALS(
* EXP = LO_OBJECT
* ACT = LO_OBJECT_RECOVERED
** MSG = MSG
** LEVEL = CRITICAL
** TOL = TOL
** QUIT = METHOD
** IGNORE_HASH_SEQUENCE = ABAP_FALSE
* ).
ENDMETHOD.
Notice the type casting from the serliazable object back to the object type!!!