"-Begin-----------------------------------------------------------------
Function Z_RFC_READ_TABLE_JSON.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(QUERY_TABLE) TYPE DD02L-TABNAME
*" VALUE(DELIMITER) TYPE SONV-FLAG DEFAULT SPACE
*" VALUE(NO_DATA) TYPE SONV-FLAG DEFAULT SPACE
*" VALUE(ROWSKIPS) TYPE SOID-ACCNT DEFAULT 0
*" VALUE(ROWCOUNT) TYPE SOID-ACCNT DEFAULT 0
*" VALUE(SORT) TYPE CHAR1024 DEFAULT SPACE
*" EXPORTING
*" VALUE(DATA_JSON) TYPE SDBLIN1024_TAB
*" TABLES
*" OPTIONS STRUCTURE ZRFC_DB_OPT
*" FIELDS STRUCTURE RFC_DB_FLD
*" DATA STRUCTURE ZTAB8192
*" EXCEPTIONS
*" TABLE_NOT_AVAILABLE
*" TABLE_WITHOUT_DATA
*" OPTION_NOT_VALID
*" FIELD_NOT_VALID
*" DATA_BUFFER_EXCEEDED
*"----------------------------------------------------------------------
"Create a structure called ZRFC_DB_OPT with the component TEXT and the
"component type CHAR1024.
"Create a domain called ZSYSCHAR8192 with the data type CHAR and the
"length 8192.
"Create a structure called ZTAB8192 with the component WA and the new
"component type ZSYSCHAR8192. In this data type add the domain
"ZSYSCHAR8192.
* ----------------------------------------------------------------------
* find out about the structure of QUERY_TABLE
* ----------------------------------------------------------------------
DATA BEGIN OF TABLE_STRUCTURE OCCURS 10.
INCLUDE STRUCTURE DFIES.
DATA END OF TABLE_STRUCTURE.
DATA:
TABLE_TYPE TYPE DD02V-TABCLASS,
strJSON Type SDBLIN1024,
cntData Type i,
cntLine Type i,
Len Type i,
LastChar(1) Type c
.
CALL FUNCTION 'DDIF_FIELDINFO_GET'
EXPORTING
TABNAME = QUERY_TABLE
* FIELDNAME = ' '
* LANGU = SY-LANGU
* LFIELDNAME = ' '
* ALL_TYPES = ' '
* GROUP_NAMES = ' '
IMPORTING
* X030L_WA =
DDOBJTYPE = TABLE_TYPE
* DFIES_WA =
* LINES_DESCR =
TABLES
DFIES_TAB = TABLE_STRUCTURE
* FIXED_VALUES =
EXCEPTIONS
NOT_FOUND = 1
INTERNAL_ERROR = 2
OTHERS = 3
.
IF SY-SUBRC <> 0.
RAISE TABLE_NOT_AVAILABLE.
ENDIF.
IF TABLE_TYPE = 'INTTAB'.
RAISE TABLE_WITHOUT_DATA.
ENDIF.
* ----------------------------------------------------------------------
* isolate first field of DATA as output field
* (i.e. allow for changes to structure DATA!)
* ----------------------------------------------------------------------
DATA LINE_LENGTH TYPE I.
FIELD-SYMBOLS .
ASSIGN COMPONENT 0 OF STRUCTURE DATA TO .
DESCRIBE FIELD LENGTH LINE_LENGTH in character mode.
* ----------------------------------------------------------------------
* if FIELDS are not specified, read all available fields
* ----------------------------------------------------------------------
DATA NUMBER_OF_FIELDS TYPE I.
DESCRIBE TABLE FIELDS LINES NUMBER_OF_FIELDS.
IF NUMBER_OF_FIELDS = 0.
LOOP AT TABLE_STRUCTURE.
MOVE TABLE_STRUCTURE-FIELDNAME TO FIELDS-FIELDNAME.
APPEND FIELDS.
ENDLOOP.
ENDIF.
* ----------------------------------------------------------------------
* for each field which has to be read, copy structure information
* into tables FIELDS_INT (internal use) and FIELDS (output)
* ----------------------------------------------------------------------
DATA: BEGIN OF FIELDS_INT OCCURS 10,
FIELDNAME LIKE TABLE_STRUCTURE-FIELDNAME,
TYPE LIKE TABLE_STRUCTURE-INTTYPE,
DECIMALS LIKE TABLE_STRUCTURE-DECIMALS,
LENGTH_SRC LIKE TABLE_STRUCTURE-INTLEN,
LENGTH_DST LIKE TABLE_STRUCTURE-LENG,
OFFSET_SRC LIKE TABLE_STRUCTURE-OFFSET,
OFFSET_DST LIKE TABLE_STRUCTURE-OFFSET,
END OF FIELDS_INT,
LINE_CURSOR TYPE I.
LINE_CURSOR = 0.
* for each field which has to be read ...
LOOP AT FIELDS.
READ TABLE TABLE_STRUCTURE WITH KEY FIELDNAME = FIELDS-FIELDNAME.
IF SY-SUBRC NE 0.
RAISE FIELD_NOT_VALID.
ENDIF.
* compute the place for field contents in DATA rows:
* if not first field in row, allow space for delimiter
IF LINE_CURSOR <> 0.
IF NO_DATA EQ SPACE AND DELIMITER NE SPACE.
MOVE DELIMITER TO DATA+LINE_CURSOR.
ENDIF.
LINE_CURSOR = LINE_CURSOR + STRLEN( DELIMITER ).
ENDIF.
* ... copy structure information into tables FIELDS_INT
* (which is used internally during SELECT) ...
FIELDS_INT-FIELDNAME = TABLE_STRUCTURE-FIELDNAME.
FIELDS_INT-LENGTH_SRC = TABLE_STRUCTURE-INTLEN.
FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-LENG.
FIELDS_INT-OFFSET_SRC = TABLE_STRUCTURE-OFFSET.
FIELDS_INT-OFFSET_DST = LINE_CURSOR.
FIELDS_INT-TYPE = TABLE_STRUCTURE-INTTYPE.
FIELDS_INT-DECIMALS = TABLE_STRUCTURE-DECIMALS.
* compute the place for contents of next field in DATA rows
LINE_CURSOR = LINE_CURSOR + TABLE_STRUCTURE-LENG.
IF LINE_CURSOR > LINE_LENGTH AND NO_DATA EQ SPACE.
RAISE DATA_BUFFER_EXCEEDED.
ENDIF.
APPEND FIELDS_INT.
* ... and into table FIELDS (which is output to the caller)
FIELDS-FIELDTEXT = TABLE_STRUCTURE-FIELDTEXT.
FIELDS-TYPE = TABLE_STRUCTURE-INTTYPE.
FIELDS-LENGTH = FIELDS_INT-LENGTH_DST.
FIELDS-OFFSET = FIELDS_INT-OFFSET_DST.
MODIFY FIELDS.
ENDLOOP.
* end of loop at FIELDS
* ----------------------------------------------------------------------
* read data from the database and copy relevant portions into DATA
* ----------------------------------------------------------------------
* output data only if NO_DATA equals space (otherwise the structure
* information in FIELDS is the only result of the module)
IF NO_DATA EQ SPACE.
data: dref type ref to data.
field-symbols: type any, type any.
create data dref type (query_table).
assign dref->* to .
SELECT * FROM (QUERY_TABLE) INTO WHERE (OPTIONS) ORDER BY (SORT).
IF SY-DBCNT GT ROWSKIPS.
* copy all relevant fields into DATA (output) table
LOOP AT FIELDS_INT.
IF FIELDS_INT-TYPE = 'P'.
ASSIGN COMPONENT FIELDS_INT-FIELDNAME
OF STRUCTURE TO
TYPE FIELDS_INT-TYPE
DECIMALS FIELDS_INT-DECIMALS.
ELSE.
ASSIGN COMPONENT FIELDS_INT-FIELDNAME
OF STRUCTURE TO
TYPE FIELDS_INT-TYPE.
ENDIF.
MOVE TO
+FIELDS_INT-OFFSET_DST(FIELDS_INT-LENGTH_DST).
ENDLOOP.
* end of loop at FIELDS_INT
APPEND DATA.
IF ROWCOUNT > 0 AND SY-DBCNT GE ROWCOUNT. EXIT. ENDIF.
ENDIF.
ENDSELECT.
"-Export data in JSON format------------------------------------------
"-
"- Check the created JSON file with http://www.jsonlint.com validator
"-
"---------------------------------------------------------------------
Describe Table DATA Lines cntData.
strJSON = `{`.
Append strJSON To DATA_JSON.
Concatenate ` "` QUERY_TABLE '" : [' Into strJSON.
Append strJSON To DATA_JSON.
Loop At DATA.
cntLine = cntLine + 1.
strJSON = ` {`.
Append strJSON To DATA_JSON.
Loop At FIELDS.
Move DATA-WA+FIELDS-OFFSET(FIELDS-LENGTH) To strJSON.
Condense strJSON.
Case FIELDS-TYPE.
When 'I' Or 'b' Or 's' Or 'P' Or 'F'.
Len = StrLen( strJSON ) - 1.
Move strJSON+Len(1) To LastChar.
If LastChar = '-'.
Move strJSON+0(Len) To strJSON.
Concatenate '-' strJSON Into strJSON.
EndIf.
Concatenate ` "` FIELDS-FIELDNAME `" : ` strJSON
Into strJSON.
When Others.
Concatenate ` "` FIELDS-FIELDNAME `" : "` strJSON '"'
Into strJSON.
EndCase.
If sy-tabix < sy-tfill.
Concatenate strJSON ',' Into strJSON.
EndIf.
Append strJSON To DATA_JSON.
EndLoop.
strJSON = ` }`.
If cntLine < cntData.
Concatenate strJSON ',' Into strJSON.
EndIf.
Append strJSON To DATA_JSON.
EndLoop.
strJSON = ` ]`.
Append strJSON To DATA_JSON.
strJSON = `}`.
Append strJSON To DATA_JSON.
ENDIF.
EndFunction.
"-End-------------------------------------------------------------------