From 3a7fc04b38f1fa6a941589cc54a3d0aa1496e107 Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Tue, 2 Jan 2024 09:59:09 +0100 Subject: [PATCH] TABL DDL, basic serialization and deser (#6721) --- package.json | 8 +- src/objects/tabl/package.devc.xml | 10 + .../zcl_abapgit_object_tabl.clas.abap | 0 ...l_abapgit_object_tabl.clas.locals_imp.abap | 0 ..._abapgit_object_tabl.clas.testclasses.abap | 0 .../zcl_abapgit_object_tabl.clas.xml | 0 .../zcl_abapgit_object_tabl_compar.clas.abap | 0 .../zcl_abapgit_object_tabl_compar.clas.xml | 0 .../zcl_abapgit_object_tabl_ddl.clas.abap | 517 ++++++++++++++++++ ...pgit_object_tabl_ddl.clas.testclasses.abap | 466 ++++++++++++++++ .../tabl/zcl_abapgit_object_tabl_ddl.clas.xml | 17 + .../zif_abapgit_object_tabl.intf.abap | 0 .../zif_abapgit_object_tabl.intf.xml | 0 test/abap_transpile.json | 13 +- 14 files changed, 1022 insertions(+), 9 deletions(-) create mode 100644 src/objects/tabl/package.devc.xml rename src/objects/{ => tabl}/zcl_abapgit_object_tabl.clas.abap (100%) rename src/objects/{ => tabl}/zcl_abapgit_object_tabl.clas.locals_imp.abap (100%) rename src/objects/{ => tabl}/zcl_abapgit_object_tabl.clas.testclasses.abap (100%) rename src/objects/{ => tabl}/zcl_abapgit_object_tabl.clas.xml (100%) rename src/objects/{ => tabl}/zcl_abapgit_object_tabl_compar.clas.abap (100%) rename src/objects/{ => tabl}/zcl_abapgit_object_tabl_compar.clas.xml (100%) create mode 100644 src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.abap create mode 100644 src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.testclasses.abap create mode 100644 src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.xml rename src/objects/{ => tabl}/zif_abapgit_object_tabl.intf.abap (100%) rename src/objects/{ => tabl}/zif_abapgit_object_tabl.intf.xml (100%) diff --git a/package.json b/package.json index 151da34e7..eed6832c6 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,12 @@ ] }, "devDependencies": { - "@abaplint/cli": "^2.103.6", + "@abaplint/cli": "^2.105.6", "@abaplint/database-sqlite": "^2.7.119", - "@abaplint/runtime": "^2.7.135", - "@abaplint/transpiler-cli": "^2.7.135", + "@abaplint/runtime": "^2.7.138", + "@abaplint/transpiler-cli": "^2.7.138", "abapmerge": "^0.16.0", "c8": "^8.0.1", - "eslint": "^8.53.0" + "eslint": "^8.56.0" } } diff --git a/src/objects/tabl/package.devc.xml b/src/objects/tabl/package.devc.xml new file mode 100644 index 000000000..25df9318d --- /dev/null +++ b/src/objects/tabl/package.devc.xml @@ -0,0 +1,10 @@ + + + + + + abapGit - TABL + + + + diff --git a/src/objects/zcl_abapgit_object_tabl.clas.abap b/src/objects/tabl/zcl_abapgit_object_tabl.clas.abap similarity index 100% rename from src/objects/zcl_abapgit_object_tabl.clas.abap rename to src/objects/tabl/zcl_abapgit_object_tabl.clas.abap diff --git a/src/objects/zcl_abapgit_object_tabl.clas.locals_imp.abap b/src/objects/tabl/zcl_abapgit_object_tabl.clas.locals_imp.abap similarity index 100% rename from src/objects/zcl_abapgit_object_tabl.clas.locals_imp.abap rename to src/objects/tabl/zcl_abapgit_object_tabl.clas.locals_imp.abap diff --git a/src/objects/zcl_abapgit_object_tabl.clas.testclasses.abap b/src/objects/tabl/zcl_abapgit_object_tabl.clas.testclasses.abap similarity index 100% rename from src/objects/zcl_abapgit_object_tabl.clas.testclasses.abap rename to src/objects/tabl/zcl_abapgit_object_tabl.clas.testclasses.abap diff --git a/src/objects/zcl_abapgit_object_tabl.clas.xml b/src/objects/tabl/zcl_abapgit_object_tabl.clas.xml similarity index 100% rename from src/objects/zcl_abapgit_object_tabl.clas.xml rename to src/objects/tabl/zcl_abapgit_object_tabl.clas.xml diff --git a/src/objects/zcl_abapgit_object_tabl_compar.clas.abap b/src/objects/tabl/zcl_abapgit_object_tabl_compar.clas.abap similarity index 100% rename from src/objects/zcl_abapgit_object_tabl_compar.clas.abap rename to src/objects/tabl/zcl_abapgit_object_tabl_compar.clas.abap diff --git a/src/objects/zcl_abapgit_object_tabl_compar.clas.xml b/src/objects/tabl/zcl_abapgit_object_tabl_compar.clas.xml similarity index 100% rename from src/objects/zcl_abapgit_object_tabl_compar.clas.xml rename to src/objects/tabl/zcl_abapgit_object_tabl_compar.clas.xml diff --git a/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.abap b/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.abap new file mode 100644 index 000000000..d5bdd1abc --- /dev/null +++ b/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.abap @@ -0,0 +1,517 @@ +CLASS zcl_abapgit_object_tabl_ddl DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + TYPES: BEGIN OF ty_dd03p, + fieldname TYPE c LENGTH 30, + keyflag TYPE abap_bool, + notnull TYPE abap_bool, + datatype TYPE c LENGTH 30, + rollname TYPE c LENGTH 30, + leng TYPE n LENGTH 6, + intlen TYPE n LENGTH 6, + inttype TYPE c LENGTH 1, + END OF ty_dd03p. + + TYPES: BEGIN OF ty_dd05m, + fieldname TYPE c LENGTH 30, + fortable TYPE c LENGTH 30, + forkey TYPE c LENGTH 30, + checktable TYPE c LENGTH 30, + checkfield TYPE c LENGTH 30, + primpos TYPE n LENGTH 4, + END OF ty_dd05m. + + TYPES: BEGIN OF ty_dd08v, + fieldname TYPE c LENGTH 30, + checktable TYPE c LENGTH 30, + ddtext TYPE string, + frkart TYPE c LENGTH 10, + card TYPE c LENGTH 1, + cardleft TYPE c LENGTH 1, + END OF ty_dd08v. + + TYPES: BEGIN OF ty_internal, + BEGIN OF dd02v, + tabname TYPE c LENGTH 30, + contflag TYPE c LENGTH 1, + exclass TYPE c LENGTH 1, + mainflag TYPE c LENGTH 1, + ddtext TYPE string, + tabclass TYPE string, + END OF dd02v, + dd03p_table TYPE STANDARD TABLE OF ty_dd03p WITH DEFAULT KEY, + dd05m_table TYPE STANDARD TABLE OF ty_dd05m WITH DEFAULT KEY, + dd08v_table TYPE STANDARD TABLE OF ty_dd08v WITH DEFAULT KEY, + END OF ty_internal. + + METHODS serialize + IMPORTING + is_data TYPE ty_internal + RETURNING + VALUE(rv_ddl) TYPE string. + + METHODS deserialize + IMPORTING + iv_ddl TYPE string + RETURNING + VALUE(rs_data) TYPE ty_internal. + + PROTECTED SECTION. + PRIVATE SECTION. + + METHODS parse_top_annotations + CHANGING + cs_data TYPE ty_internal + cv_ddl TYPE string. + + METHODS parse_field_annotations + EXPORTING + es_dd08v TYPE ty_dd08v + CHANGING + cv_ddl TYPE string. + + METHODS parse_field + IMPORTING + iv_field TYPE string + CHANGING + cs_data TYPE ty_internal. + + METHODS serialize_top + IMPORTING + is_data TYPE ty_internal + RETURNING + VALUE(rv_ddl) TYPE string. + + METHODS serialize_field_annotations + IMPORTING + iv_fieldname TYPE clike + is_data TYPE ty_internal + RETURNING + VALUE(rv_ddl) TYPE string. + + METHODS serialize_field_foreign_key + IMPORTING + iv_fieldname TYPE clike + is_data TYPE ty_internal + RETURNING + VALUE(rv_ddl) TYPE string. + + METHODS escape_string + IMPORTING + iv_string TYPE clike + RETURNING + VALUE(rv_string) TYPE string. + + METHODS unescape_string + IMPORTING + iv_string TYPE clike + RETURNING + VALUE(rv_string) TYPE string. + + METHODS serialize_type + IMPORTING is_dd03p TYPE ty_dd03p + RETURNING VALUE(rv_type) TYPE string. + + METHODS parse_type + IMPORTING iv_token TYPE string + CHANGING cs_dd03p TYPE ty_dd03p. +ENDCLASS. + + + +CLASS zcl_abapgit_object_tabl_ddl IMPLEMENTATION. + + METHOD unescape_string. + rv_string = iv_string. + REPLACE FIRST OCCURRENCE OF REGEX |^'| IN rv_string WITH ||. + REPLACE FIRST OCCURRENCE OF REGEX |'$| IN rv_string WITH ||. + ENDMETHOD. + + METHOD escape_string. +* todo + rv_string = |'{ iv_string }'|. + ENDMETHOD. + + METHOD parse_type. + + DATA lv_token TYPE string. + + lv_token = iv_token. + IF lv_token CP 'abap.*'. + lv_token = lv_token+5. + IF lv_token(4) = 'char'. +* todo, length + cs_dd03p-datatype = 'CHAR'. + ELSEIF lv_token(6) = 'string'. + cs_dd03p-intlen = 8. + cs_dd03p-inttype = 'g'. + cs_dd03p-datatype = 'STRG'. + ELSE. + ASSERT 1 = 'todo'. + ENDIF. + ELSE. + cs_dd03p-rollname = to_upper( lv_token ). + ENDIF. + + ENDMETHOD. + + METHOD parse_top_annotations. + + DATA lv_annotation TYPE string. + DATA lv_name TYPE string. + DATA lv_value TYPE string. + + + WHILE cv_ddl CP '@*'. + SPLIT cv_ddl AT |\n| INTO lv_annotation cv_ddl. + SPLIT lv_annotation AT ':' INTO lv_name lv_value. + CONDENSE lv_name. + CONDENSE lv_value. + ASSERT lv_name IS NOT INITIAL. + ASSERT lv_value IS NOT INITIAL. + + + CASE lv_name. + WHEN '@EndUserText.label'. + cs_data-dd02v-ddtext = unescape_string( lv_value ). + WHEN '@AbapCatalog.enhancementCategory'. + CASE lv_value. + WHEN '#NOT_EXTENSIBLE'. + cs_data-dd02v-contflag = '1'. + WHEN OTHERS. + ASSERT 1 = 'todo'. + ENDCASE. + WHEN '@AbapCatalog.tableCategory'. + CASE lv_value. + WHEN '#TRANSPARENT'. + cs_data-dd02v-tabclass = 'TRANSP'. + WHEN OTHERS. + ASSERT 1 = 'todo'. + ENDCASE. + WHEN '@AbapCatalog.deliveryClass'. + ASSERT lv_value(1) = '#'. + cs_data-dd02v-contflag = lv_value+1. + WHEN '@AbapCatalog.dataMaintenance'. + CASE lv_value. + WHEN '#ALLOWED'. + cs_data-dd02v-mainflag = abap_true. + WHEN '#LIMITED'. + cs_data-dd02v-mainflag = abap_false. + WHEN OTHERS. + ASSERT 1 = 'todo'. + ENDCASE. + WHEN OTHERS. + WRITE: / 'todo:', lv_name, lv_value. + ASSERT 1 = 'todo'. + ENDCASE. + + ENDWHILE. + + ENDMETHOD. + + METHOD deserialize. + +* https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/abenddicddl_define_table.htm + +* CL_DDL_PARSER, CL_SBD_STRUCTURE_OBJDATA serializer in local class? +" todo, NEW cl_sbd_structure_persist( )->get_source( +" EXPORTING +" i_object_key = 'ZABAPGIT' +" IMPORTING +" e_source = DATA(sdf) ). + + DATA lv_ddl TYPE string. + DATA lv_fields TYPE string. + DATA lv_start TYPE i. + DATA lv_length TYPE i. + DATA lv_end TYPE i. + DATA lt_fields TYPE STANDARD TABLE OF string WITH DEFAULT KEY. + DATA lv_field TYPE string. + + + lv_ddl = iv_ddl. + + parse_top_annotations( CHANGING + cs_data = rs_data + cv_ddl = lv_ddl ). + + FIND FIRST OCCURRENCE OF '{' IN lv_ddl MATCH OFFSET lv_start. + ASSERT lv_start > 0. + FIND FIRST OCCURRENCE OF '}' IN lv_ddl MATCH OFFSET lv_end. + ASSERT lv_end > 0. + + lv_start = lv_start + 1. + lv_length = lv_end - lv_start - 1. + lv_fields = lv_ddl+lv_start(lv_length). + SPLIT lv_fields AT |;| INTO TABLE lt_fields. + + LOOP AT lt_fields INTO lv_field WHERE table_line IS NOT INITIAL. + parse_field( EXPORTING iv_field = lv_field CHANGING cs_data = rs_data ). + ENDLOOP. + + ENDMETHOD. + + METHOD parse_field_annotations. + + DATA lv_annotation TYPE string. + DATA lv_name TYPE string. + DATA lv_value TYPE string. + + + REPLACE FIRST OCCURRENCE OF REGEX '^[\n ]*' IN cv_ddl WITH ||. + + WHILE cv_ddl CP '@*'. + SPLIT cv_ddl AT |\n| INTO lv_annotation cv_ddl. + CONDENSE cv_ddl. + + SPLIT lv_annotation AT ':' INTO lv_name lv_value. + CONDENSE lv_name. + CONDENSE lv_value. + ASSERT lv_name IS NOT INITIAL. + ASSERT lv_value IS NOT INITIAL. + + CASE lv_name. + WHEN '@AbapCatalog.foreignKey.label'. + es_dd08v-ddtext = unescape_string( lv_value ). + WHEN '@AbapCatalog.foreignKey.keyType'. + ASSERT lv_value(1) = '#'. + es_dd08v-frkart = lv_value+1. + WHEN '@AbapCatalog.foreignKey.screenCheck'. + ASSERT lv_value = 'true'. + WHEN OTHERS. + WRITE: / 'todo:', lv_name, lv_value. + ASSERT 1 = 'todo'. + ENDCASE. + ENDWHILE. + + ENDMETHOD. + + METHOD parse_field. + + CONSTANTS: BEGIN OF lc_mode, + start TYPE i VALUE 0, + colon TYPE i VALUE 1, + type TYPE i VALUE 2, + aftertype TYPE i VALUE 2, + null TYPE i VALUE 2, + afternull TYPE i VALUE 2, + END OF lc_mode. + + DATA lv_field TYPE string. + DATA lv_mode TYPE i. + DATA lt_tokens TYPE STANDARD TABLE OF string WITH DEFAULT KEY. + DATA lv_token TYPE string. + DATA ls_dd08v TYPE ty_dd08v. + + FIELD-SYMBOLS LIKE LINE OF cs_data-dd03p_table. + + + lv_field = iv_field. + parse_field_annotations( + IMPORTING es_dd08v = ls_dd08v + CHANGING cv_ddl = lv_field ). + + SPLIT lv_field AT space INTO TABLE lt_tokens. + + APPEND INITIAL LINE TO cs_data-dd03p_table ASSIGNING . + + LOOP AT lt_tokens INTO lv_token WHERE table_line IS NOT INITIAL. + CASE lv_mode. + WHEN lc_mode-start. +* todo, is it possible to have a key field named "key" ? + IF lv_token = 'key'. + -keyflag = abap_true. + ELSE. + -fieldname = to_upper( lv_token ). + lv_mode = lc_mode-colon. + ENDIF. + WHEN lc_mode-colon. + ASSERT lv_token = ':'. + lv_mode = lc_mode-type. + WHEN lc_mode-type. + parse_type( + EXPORTING iv_token = lv_token + CHANGING cs_dd03p = ). + RETURN. + WHEN lc_mode-aftertype. + IF lv_token = 'not'. + -notnull = abap_true. + lv_mode = lc_mode-null. + ENDIF. + WHEN lc_mode-null. + ASSERT lv_token = 'null'. + lv_mode = lc_mode-afternull. + WHEN lc_mode-afternull. + ASSERT lv_token = 'with'. + RETURN. " todo + WHEN OTHERS. + ASSERT 1 = 'todo'. + ENDCASE. + ENDLOOP. + + ENDMETHOD. + + METHOD serialize_top. + + rv_ddl = rv_ddl && |@EndUserText.label : { escape_string( is_data-dd02v-ddtext ) }\n|. + + CASE is_data-dd02v-exclass. + WHEN '1'. + rv_ddl = rv_ddl && |@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE\n|. + WHEN OTHERS. + ASSERT 1 = 'todo'. + ENDCASE. + + CASE is_data-dd02v-tabclass. + WHEN 'TRANSP'. + rv_ddl = rv_ddl && |@AbapCatalog.tableCategory : #TRANSPARENT\n|. + WHEN OTHERS. + ASSERT 1 = 'todo'. + ENDCASE. + + rv_ddl = rv_ddl && |@AbapCatalog.deliveryClass : #{ is_data-dd02v-contflag }\n|. + + IF is_data-dd02v-mainflag = abap_true. + rv_ddl = rv_ddl && |@AbapCatalog.dataMaintenance : #ALLOWED\n|. + ELSE. + rv_ddl = rv_ddl && |@AbapCatalog.dataMaintenance : #LIMITED\n|. + ENDIF. + + ENDMETHOD. + + METHOD serialize_field_annotations. + + DATA ls_dd08v LIKE LINE OF is_data-dd08v_table. + + READ TABLE is_data-dd08v_table INTO ls_dd08v WITH KEY fieldname = iv_fieldname. + IF sy-subrc <> 0. + RETURN. + ENDIF. + + IF ls_dd08v-ddtext IS NOT INITIAL. + rv_ddl = rv_ddl && | @AbapCatalog.foreignKey.label : { escape_string( ls_dd08v-ddtext ) }\n|. + ENDIF. + + rv_ddl = rv_ddl && | @AbapCatalog.foreignKey.keyType : #{ ls_dd08v-frkart }\n|. + + rv_ddl = rv_ddl && | @AbapCatalog.foreignKey.screenCheck : true\n|. + + ENDMETHOD. + + METHOD serialize_field_foreign_key. + + DATA ls_dd08v LIKE LINE OF is_data-dd08v_table. + DATA ls_dd05m LIKE LINE OF is_data-dd05m_table. + DATA lv_pre TYPE string. + DATA lv_cardinality TYPE string. + + READ TABLE is_data-dd08v_table INTO ls_dd08v WITH KEY fieldname = iv_fieldname. + IF sy-subrc <> 0. + RETURN. + ENDIF. + + IF ls_dd08v-cardleft = 'C' AND ls_dd08v-card = '1'. + lv_cardinality = |[1,0..1]|. + ELSEIF ls_dd08v-cardleft = '1' AND ls_dd08v-card = 'N'. + lv_cardinality = |[1..*,1]|. + ELSE. + ASSERT 1 = 'todo'. + ENDIF. + + rv_ddl = rv_ddl && |\n with foreign key { lv_cardinality } { to_lower( ls_dd08v-checktable ) }|. + +* assumption: dd05m table is sorted by PRIMPOS ascending + LOOP AT is_data-dd05m_table INTO ls_dd05m WHERE fieldname = iv_fieldname. + IF lv_pre IS INITIAL. + lv_pre = |\n where |. + ELSE. + lv_pre = |\n and |. + ENDIF. + rv_ddl = rv_ddl && |{ lv_pre }{ to_lower( ls_dd05m-checkfield ) } = { + to_lower( ls_dd05m-fortable ) }.{ to_lower( ls_dd05m-forkey ) }|. + ENDLOOP. + + ENDMETHOD. + + METHOD serialize. + + DATA ls_dd03p LIKE LINE OF is_data-dd03p_table. + DATA lv_key TYPE string. + DATA lv_type TYPE string. + DATA lv_pre TYPE string. + DATA lv_int TYPE i. + DATA lv_colon TYPE i. + + + rv_ddl = rv_ddl && serialize_top( is_data ). + + rv_ddl = rv_ddl && |define table { to_lower( is_data-dd02v-tabname ) } \{\n|. + + LOOP AT is_data-dd03p_table INTO ls_dd03p. + lv_int = 0. + IF ls_dd03p-keyflag = abap_true. + lv_int = 4. + ENDIF. + lv_int = lv_int + strlen( ls_dd03p-fieldname ). + IF lv_int > lv_colon. + lv_colon = lv_int. + ENDIF. + ENDLOOP. + + LOOP AT is_data-dd03p_table INTO ls_dd03p. + CLEAR lv_key. + IF ls_dd03p-keyflag = abap_true. + lv_key = |key |. + ENDIF. + + rv_ddl = rv_ddl && serialize_field_annotations( + iv_fieldname = ls_dd03p-fieldname + is_data = is_data ). + + lv_type = serialize_type( ls_dd03p ). + + lv_pre = |{ lv_key }{ to_lower( ls_dd03p-fieldname ) }|. + IF strlen( lv_pre ) < lv_colon. + lv_pre = lv_pre && repeat( + val = | | + occ = lv_colon - strlen( lv_pre ) ). + ENDIF. + rv_ddl = rv_ddl && | { lv_pre } : { lv_type }|. + rv_ddl = rv_ddl && serialize_field_foreign_key( + iv_fieldname = ls_dd03p-fieldname + is_data = is_data ). + rv_ddl = rv_ddl && |;\n|. + ENDLOOP. + rv_ddl = rv_ddl && |\n|. + + rv_ddl = rv_ddl && |\}|. + + ENDMETHOD. + + METHOD serialize_type. + + DATA lv_notnull TYPE string. + DATA lv_int TYPE i. + + IF is_dd03p-notnull = abap_true. + lv_notnull = | not null|. + ENDIF. + + IF is_dd03p-rollname IS NOT INITIAL. + rv_type = |{ to_lower( is_dd03p-rollname ) }{ lv_notnull }|. + ELSE. + lv_int = is_dd03p-leng. + CASE is_dd03p-datatype. + WHEN 'STRG'. + rv_type = |abap.string(0)|. + WHEN OTHERS. + rv_type = |abap.{ to_lower( is_dd03p-datatype ) }({ lv_int }){ lv_notnull }|. + ENDCASE. + ENDIF. + + ENDMETHOD. + +ENDCLASS. diff --git a/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.testclasses.abap b/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.testclasses.abap new file mode 100644 index 000000000..b2ba5dc7f --- /dev/null +++ b/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.testclasses.abap @@ -0,0 +1,466 @@ +CLASS ltcl_test DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS FINAL. + + PRIVATE SECTION. + METHODS test + IMPORTING + iv_ddl TYPE string + iv_xml TYPE string. + + METHODS dump_xml + IMPORTING + is_internal TYPE zcl_abapgit_object_tabl_ddl=>ty_internal + RETURNING + VALUE(rv_xml) TYPE string. + + METHODS test1 FOR TESTING RAISING cx_static_check. + METHODS test2 FOR TESTING RAISING cx_static_check. + +ENDCLASS. + + +CLASS ltcl_test IMPLEMENTATION. + + METHOD test. + + DATA lo_format TYPE REF TO zcl_abapgit_object_tabl_ddl. + DATA ls_data TYPE zcl_abapgit_object_tabl_ddl=>ty_internal. + DATA ls_deserialized TYPE zcl_abapgit_object_tabl_ddl=>ty_internal. + DATA lv_ddl TYPE string. + DATA lv_xml TYPE string. + + + CREATE OBJECT lo_format. + + CALL TRANSFORMATION id + OPTIONS value_handling = 'accept_data_loss' + SOURCE XML iv_xml + RESULT + dd02v = ls_data-dd02v + dd03p_table = ls_data-dd03p_table + dd05m_table = ls_data-dd05m_table + dd08v_table = ls_data-dd08v_table. + + lv_ddl = lo_format->serialize( ls_data ). + + cl_abap_unit_assert=>assert_equals( + exp = iv_ddl + act = lv_ddl ). + + ls_deserialized = lo_format->deserialize( lv_ddl ). + + lv_xml = dump_xml( ls_deserialized ). + +* todo, check xml result + + ENDMETHOD. + + METHOD dump_xml. + + CALL TRANSFORMATION id + OPTIONS initial_components = 'suppress' + SOURCE + dd02v = is_internal-dd02v + dd03p_table = is_internal-dd03p_table + dd05m_table = is_internal-dd05m_table + dd08v_table = is_internal-dd08v_table + RESULT XML rv_xml. + + ENDMETHOD. + + METHOD test1. + + DATA lv_ddl TYPE string. + DATA lv_xml TYPE string. + + lv_ddl = + `@EndUserText.label : 'Generated by abapGit'` && |\n| && + `@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE` && |\n| && + `@AbapCatalog.tableCategory : #TRANSPARENT` && |\n| && + `@AbapCatalog.deliveryClass : #L` && |\n| && + `@AbapCatalog.dataMaintenance : #LIMITED` && |\n| && + `define table zabapgit {` && |\n| && + ` key type : abap.char(12) not null;` && |\n| && + ` key value : abap.char(12) not null;` && |\n| && + ` data_str : abap.string(0);` && |\n| && + `` && |\n| && + `}`. + + lv_xml = + `` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ZABAPGIT` && |\n| && + ` E` && |\n| && + ` TRANSP` && |\n| && + ` Generated by abapGit` && |\n| && + ` E` && |\n| && + ` L` && |\n| && + ` 1` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ZABAPGIT` && |\n| && + ` A` && |\n| && + ` 1` && |\n| && + ` APPL1` && |\n| && + ` N` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` TYPE` && |\n| && + ` X` && |\n| && + ` 0` && |\n| && + ` C` && |\n| && + ` 000024` && |\n| && + ` X` && |\n| && + ` CHAR` && |\n| && + ` 000012` && |\n| && + ` CHAR` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` VALUE` && |\n| && + ` X` && |\n| && + ` 0` && |\n| && + ` C` && |\n| && + ` 000024` && |\n| && + ` X` && |\n| && + ` CHAR` && |\n| && + ` 000012` && |\n| && + ` CHAR` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` DATA_STR` && |\n| && + ` 0` && |\n| && + ` g` && |\n| && + ` 000008` && |\n| && + ` STRG` && |\n| && + ` STRG` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` `. + + test( iv_xml = lv_xml + iv_ddl = lv_ddl ). + + ENDMETHOD. + + METHOD test2. + + DATA lv_ddl TYPE string. + DATA lv_xml TYPE string. + + lv_ddl = + `@EndUserText.label : 'Clients'` && |\n| && + `@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE` && |\n| && + `@AbapCatalog.tableCategory : #TRANSPARENT` && |\n| && + `@AbapCatalog.deliveryClass : #C` && |\n| && + `@AbapCatalog.dataMaintenance : #ALLOWED` && |\n| && + `define table t000 {` && |\n| && + ` key mandt : mandt not null;` && |\n| && + ` mtext : mtext_d not null;` && |\n| && + ` ort01 : ort01 not null;` && |\n| && + ` @AbapCatalog.foreignKey.keyType : #KEY` && |\n| && + ` @AbapCatalog.foreignKey.screenCheck : true` && |\n| && + ` mwaer : mwaer not null` && |\n| && + ` with foreign key [1..*,1] tcurc` && |\n| && + ` where mandt = t000.mandt` && |\n| && + ` and waers = t000.mwaer;` && |\n| && + ` adrnr : char10 not null;` && |\n| && + ` cccategory : cccategory not null;` && |\n| && + ` cccoractiv : cccoractiv not null;` && |\n| && + ` ccnocliind : ccnocliind not null;` && |\n| && + ` cccopylock : cccopylock not null;` && |\n| && + ` ccnocascad : ccnocascad not null;` && |\n| && + ` ccsoftlock : ccsoftlock not null;` && |\n| && + ` ccorigcont : ccorigcont not null;` && |\n| && + ` ccimaildis : ccimaildis not null;` && |\n| && + ` cctemplock : cctemplock not null;` && |\n| && + ` changeuser : as4user not null;` && |\n| && + ` changedate : as4date not null;` && |\n| && + ` @AbapCatalog.foreignKey.label : 'Logical system'` && |\n| && + ` @AbapCatalog.foreignKey.keyType : #KEY` && |\n| && + ` @AbapCatalog.foreignKey.screenCheck : true` && |\n| && + ` logsys : logsys not null` && |\n| && + ` with foreign key [1,0..1] tbdls` && |\n| && + ` where logsys = t000.logsys;` && |\n| && + `` && |\n| && + `}`. + + lv_xml = + `` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` T000` && |\n| && + ` E` && |\n| && + ` TRANSP` && |\n| && + ` E` && |\n| && + ` Clients` && |\n| && + ` SAP` && |\n| && + ` D` && |\n| && + ` X` && |\n| && + ` C` && |\n| && + ` X` && |\n| && + ` 1` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` T000` && |\n| && + ` A` && |\n| && + ` 0` && |\n| && + ` APPL2` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` MANDT` && |\n| && + ` X` && |\n| && + ` MANDT` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` MTEXT` && |\n| && + ` MTEXT_D` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ORT01` && |\n| && + ` ORT01` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` MWAER` && |\n| && + ` MWAER` && |\n| && + ` TCURC` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` P` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ADRNR` && |\n| && + ` CHAR10` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCCATEGORY` && |\n| && + ` CCCATEGORY` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` F` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCCORACTIV` && |\n| && + ` CCCORACTIV` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` F` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCNOCLIIND` && |\n| && + ` CCNOCLIIND` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` F` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCCOPYLOCK` && |\n| && + ` CCCOPYLOCK` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` F` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCNOCASCAD` && |\n| && + ` CCNOCASCAD` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` F` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCSOFTLOCK` && |\n| && + ` CCSOFTLOCK` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` F` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCORIGCONT` && |\n| && + ` CCORIGCONT` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCIMAILDIS` && |\n| && + ` CCIMAILDIS` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` F` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CCTEMPLOCK` && |\n| && + ` CCTEMPLOCK` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` F` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CHANGEUSER` && |\n| && + ` AS4USER` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` E` && |\n| && + ` X` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` CHANGEDATE` && |\n| && + ` AS4DATE` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` T` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` LOGSYS` && |\n| && + ` LOGSYS` && |\n| && + ` TBDLS` && |\n| && + ` 0` && |\n| && + ` X` && |\n| && + ` P` && |\n| && + ` E` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` LOGSYS` && |\n| && + ` T000` && |\n| && + ` LOGSYS` && |\n| && + ` TBDLS` && |\n| && + ` LOGSYS` && |\n| && + ` 0001` && |\n| && + ` LOGSYS` && |\n| && + ` CHAR` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` MWAER` && |\n| && + ` T000` && |\n| && + ` MANDT` && |\n| && + ` TCURC` && |\n| && + ` MANDT` && |\n| && + ` 0001` && |\n| && + ` MANDT` && |\n| && + ` CLNT` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` MWAER` && |\n| && + ` T000` && |\n| && + ` MWAER` && |\n| && + ` TCURC` && |\n| && + ` WAERS` && |\n| && + ` 0002` && |\n| && + ` WAERS` && |\n| && + ` CUKY` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` LOGSYS` && |\n| && + ` TBDLS` && |\n| && + ` KEY` && |\n| && + ` 1` && |\n| && + ` Logical system` && |\n| && + ` C` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` MWAER` && |\n| && + ` TCURC` && |\n| && + ` KEY` && |\n| && + ` N` && |\n| && + ` 1` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` H_T000` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` H_T000` && |\n| && + ` MANDT` && |\n| && + ` 0001` && |\n| && + ` T000` && |\n| && + ` MANDT` && |\n| && + ` X` && |\n| && + ` X` && |\n| && + ` MANDT` && |\n| && + ` MANDT` && |\n| && + ` CLNT` && |\n| && + ` 000003` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` H_T000` && |\n| && + ` MTEXT` && |\n| && + ` 0002` && |\n| && + ` G` && |\n| && + ` X` && |\n| && + ` MTEXT_D` && |\n| && + ` TEXT25` && |\n| && + ` CHAR` && |\n| && + ` 000025` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` H_T000` && |\n| && + ` ORT01` && |\n| && + ` 0003` && |\n| && + ` G` && |\n| && + ` X` && |\n| && + ` ORT01` && |\n| && + ` TEXT25` && |\n| && + ` CHAR` && |\n| && + ` 000025` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` T000` && |\n| && + ` SS` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` ` && |\n| && + ` `. + + test( iv_xml = lv_xml + iv_ddl = lv_ddl ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.xml b/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.xml new file mode 100644 index 000000000..5e00098b8 --- /dev/null +++ b/src/objects/tabl/zcl_abapgit_object_tabl_ddl.clas.xml @@ -0,0 +1,17 @@ + + + + + + ZCL_ABAPGIT_OBJECT_TABL_DDL + E + abapGit - TABL DDL + 1 + X + X + X + X + + + + diff --git a/src/objects/zif_abapgit_object_tabl.intf.abap b/src/objects/tabl/zif_abapgit_object_tabl.intf.abap similarity index 100% rename from src/objects/zif_abapgit_object_tabl.intf.abap rename to src/objects/tabl/zif_abapgit_object_tabl.intf.abap diff --git a/src/objects/zif_abapgit_object_tabl.intf.xml b/src/objects/tabl/zif_abapgit_object_tabl.intf.xml similarity index 100% rename from src/objects/zif_abapgit_object_tabl.intf.xml rename to src/objects/tabl/zif_abapgit_object_tabl.intf.xml diff --git a/test/abap_transpile.json b/test/abap_transpile.json index 6b0e7f146..d10e50042 100644 --- a/test/abap_transpile.json +++ b/test/abap_transpile.json @@ -1,11 +1,12 @@ { "input_folder": "{src,deps}", "input_filter": [ - "deps/", "\\.w3mi.", + "deps/", "src/ui/zcl_abapgit_e", - "src/zcl_abapgit_e", "src/utils/*", + "src/zcl_abapgit_e", + "zag1", "src/env/*", "zcl_abapgit_adt_link", "zcl_abapgit_aff_registry", @@ -15,6 +16,7 @@ "zcl_abapgit_b", "zcl_abapgit_c", "zcl_abapgit_d", + "zcl_abapgit_exit", "zcl_abapgit_f", "zcl_abapgit_g", "zcl_abapgit_h", @@ -22,15 +24,15 @@ "zcl_abapgit_j", "zcl_abapgit_l", "zcl_abapgit_n", - "zcl_abapgit_exit", - "zcl_abapgit_object_intf", "zcl_abapgit_object_devc", + "zcl_abapgit_object_intf", + "zcl_abapgit_object_zag", + "zcl_abapgit_objects_bridge", "zcl_abapgit_objects_files", "zcl_abapgit_objects_program", "zcl_abapgit_objects_super", "zcl_abapgit_objects.clas.abap", "zcl_abapgit_objects.clas.testclasses.abap", - "zcl_abapgit_objects_bridge", "zcl_abapgit_oo_base", "zcl_abapgit_oo_factory", "zcl_abapgit_oo_interface", @@ -54,6 +56,7 @@ "zif_abapgit_l", "zif_abapgit_m", "zif_abapgit_object", + "zcl_abapgit_object_tabl_ddl", "zif_abapgit_oo_object_fnc", "zif_abapgit_p", "zif_abapgit_r",