TABL DDL, basic serialization and deser (#6721)

This commit is contained in:
Lars Hvam 2024-01-02 09:59:09 +01:00 committed by GitHub
parent e86d473140
commit 3a7fc04b38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1022 additions and 9 deletions

View File

@ -23,12 +23,12 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@abaplint/cli": "^2.103.6", "@abaplint/cli": "^2.105.6",
"@abaplint/database-sqlite": "^2.7.119", "@abaplint/database-sqlite": "^2.7.119",
"@abaplint/runtime": "^2.7.135", "@abaplint/runtime": "^2.7.138",
"@abaplint/transpiler-cli": "^2.7.135", "@abaplint/transpiler-cli": "^2.7.138",
"abapmerge": "^0.16.0", "abapmerge": "^0.16.0",
"c8": "^8.0.1", "c8": "^8.0.1",
"eslint": "^8.53.0" "eslint": "^8.56.0"
} }
} }

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DEVC>
<CTEXT>abapGit - TABL</CTEXT>
</DEVC>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -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 <ls_dd03p> 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 <ls_dd03p>.
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'.
<ls_dd03p>-keyflag = abap_true.
ELSE.
<ls_dd03p>-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 = <ls_dd03p> ).
RETURN.
WHEN lc_mode-aftertype.
IF lv_token = 'not'.
<ls_dd03p>-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.

View File

@ -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 =
`<?xml version="1.0" encoding="utf-8"?>` && |\n| &&
` <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">` && |\n| &&
` <asx:values>` && |\n| &&
` <DD02V>` && |\n| &&
` <TABNAME>ZABAPGIT</TABNAME>` && |\n| &&
` <DDLANGUAGE>E</DDLANGUAGE>` && |\n| &&
` <TABCLASS>TRANSP</TABCLASS>` && |\n| &&
` <DDTEXT>Generated by abapGit</DDTEXT>` && |\n| &&
` <MASTERLANG>E</MASTERLANG>` && |\n| &&
` <CONTFLAG>L</CONTFLAG>` && |\n| &&
` <EXCLASS>1</EXCLASS>` && |\n| &&
` </DD02V>` && |\n| &&
` <DD09L>` && |\n| &&
` <TABNAME>ZABAPGIT</TABNAME>` && |\n| &&
` <AS4LOCAL>A</AS4LOCAL>` && |\n| &&
` <TABKAT>1</TABKAT>` && |\n| &&
` <TABART>APPL1</TABART>` && |\n| &&
` <BUFALLOW>N</BUFALLOW>` && |\n| &&
` </DD09L>` && |\n| &&
` <DD03P_TABLE>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>TYPE</FIELDNAME>` && |\n| &&
` <KEYFLAG>X</KEYFLAG>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <INTTYPE>C</INTTYPE>` && |\n| &&
` <INTLEN>000024</INTLEN>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <DATATYPE>CHAR</DATATYPE>` && |\n| &&
` <LENG>000012</LENG>` && |\n| &&
` <MASK> CHAR</MASK>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>VALUE</FIELDNAME>` && |\n| &&
` <KEYFLAG>X</KEYFLAG>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <INTTYPE>C</INTTYPE>` && |\n| &&
` <INTLEN>000024</INTLEN>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <DATATYPE>CHAR</DATATYPE>` && |\n| &&
` <LENG>000012</LENG>` && |\n| &&
` <MASK> CHAR</MASK>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>DATA_STR</FIELDNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <INTTYPE>g</INTTYPE>` && |\n| &&
` <INTLEN>000008</INTLEN>` && |\n| &&
` <DATATYPE>STRG</DATATYPE>` && |\n| &&
` <MASK> STRG</MASK>` && |\n| &&
` </DD03P>` && |\n| &&
` </DD03P_TABLE>` && |\n| &&
` </asx:values>` && |\n| &&
` </asx:abap>`.
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 =
`<?xml version="1.0" encoding="utf-8"?>` && |\n| &&
` <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">` && |\n| &&
` <asx:values>` && |\n| &&
` <DD02V>` && |\n| &&
` <TABNAME>T000</TABNAME>` && |\n| &&
` <DDLANGUAGE>E</DDLANGUAGE>` && |\n| &&
` <TABCLASS>TRANSP</TABCLASS>` && |\n| &&
` <BUFFERED>E</BUFFERED>` && |\n| &&
` <DDTEXT>Clients</DDTEXT>` && |\n| &&
` <APPLCLASS>SAP</APPLCLASS>` && |\n| &&
` <MASTERLANG>D</MASTERLANG>` && |\n| &&
` <MAINFLAG>X</MAINFLAG>` && |\n| &&
` <CONTFLAG>C</CONTFLAG>` && |\n| &&
` <SHLPEXI>X</SHLPEXI>` && |\n| &&
` <EXCLASS>1</EXCLASS>` && |\n| &&
` </DD02V>` && |\n| &&
` <DD09L>` && |\n| &&
` <TABNAME>T000</TABNAME>` && |\n| &&
` <AS4LOCAL>A</AS4LOCAL>` && |\n| &&
` <TABKAT>0</TABKAT>` && |\n| &&
` <TABART>APPL2</TABART>` && |\n| &&
` <PUFFERUNG>X</PUFFERUNG>` && |\n| &&
` <PROTOKOLL>X</PROTOKOLL>` && |\n| &&
` <TRANSPFLAG>X</TRANSPFLAG>` && |\n| &&
` <BUFALLOW>X</BUFALLOW>` && |\n| &&
` </DD09L>` && |\n| &&
` <DD03P_TABLE>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>MANDT</FIELDNAME>` && |\n| &&
` <KEYFLAG>X</KEYFLAG>` && |\n| &&
` <ROLLNAME>MANDT</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>MTEXT</FIELDNAME>` && |\n| &&
` <ROLLNAME>MTEXT_D</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>ORT01</FIELDNAME>` && |\n| &&
` <ROLLNAME>ORT01</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>MWAER</FIELDNAME>` && |\n| &&
` <ROLLNAME>MWAER</ROLLNAME>` && |\n| &&
` <CHECKTABLE>TCURC</CHECKTABLE>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <SHLPORIGIN>P</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>ADRNR</FIELDNAME>` && |\n| &&
` <ROLLNAME>CHAR10</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCCATEGORY</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCCATEGORY</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <VALEXI>X</VALEXI>` && |\n| &&
` <SHLPORIGIN>F</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCCORACTIV</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCCORACTIV</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <VALEXI>X</VALEXI>` && |\n| &&
` <SHLPORIGIN>F</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCNOCLIIND</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCNOCLIIND</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <VALEXI>X</VALEXI>` && |\n| &&
` <SHLPORIGIN>F</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCCOPYLOCK</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCCOPYLOCK</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <VALEXI>X</VALEXI>` && |\n| &&
` <SHLPORIGIN>F</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCNOCASCAD</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCNOCASCAD</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <VALEXI>X</VALEXI>` && |\n| &&
` <SHLPORIGIN>F</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCSOFTLOCK</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCSOFTLOCK</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <VALEXI>X</VALEXI>` && |\n| &&
` <SHLPORIGIN>F</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCORIGCONT</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCORIGCONT</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCIMAILDIS</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCIMAILDIS</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <VALEXI>X</VALEXI>` && |\n| &&
` <SHLPORIGIN>F</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CCTEMPLOCK</FIELDNAME>` && |\n| &&
` <ROLLNAME>CCTEMPLOCK</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <VALEXI>X</VALEXI>` && |\n| &&
` <SHLPORIGIN>F</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CHANGEUSER</FIELDNAME>` && |\n| &&
` <ROLLNAME>AS4USER</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` <ANONYMOUS>X</ANONYMOUS>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>CHANGEDATE</FIELDNAME>` && |\n| &&
` <ROLLNAME>AS4DATE</ROLLNAME>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <SHLPORIGIN>T</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` <DD03P>` && |\n| &&
` <FIELDNAME>LOGSYS</FIELDNAME>` && |\n| &&
` <ROLLNAME>LOGSYS</ROLLNAME>` && |\n| &&
` <CHECKTABLE>TBDLS</CHECKTABLE>` && |\n| &&
` <ADMINFIELD>0</ADMINFIELD>` && |\n| &&
` <NOTNULL>X</NOTNULL>` && |\n| &&
` <SHLPORIGIN>P</SHLPORIGIN>` && |\n| &&
` <COMPTYPE>E</COMPTYPE>` && |\n| &&
` </DD03P>` && |\n| &&
` </DD03P_TABLE>` && |\n| &&
` <DD05M_TABLE>` && |\n| &&
` <DD05M>` && |\n| &&
` <FIELDNAME>LOGSYS</FIELDNAME>` && |\n| &&
` <FORTABLE>T000</FORTABLE>` && |\n| &&
` <FORKEY>LOGSYS</FORKEY>` && |\n| &&
` <CHECKTABLE>TBDLS</CHECKTABLE>` && |\n| &&
` <CHECKFIELD>LOGSYS</CHECKFIELD>` && |\n| &&
` <PRIMPOS>0001</PRIMPOS>` && |\n| &&
` <DOMNAME>LOGSYS</DOMNAME>` && |\n| &&
` <DATATYPE>CHAR</DATATYPE>` && |\n| &&
` </DD05M>` && |\n| &&
` <DD05M>` && |\n| &&
` <FIELDNAME>MWAER</FIELDNAME>` && |\n| &&
` <FORTABLE>T000</FORTABLE>` && |\n| &&
` <FORKEY>MANDT</FORKEY>` && |\n| &&
` <CHECKTABLE>TCURC</CHECKTABLE>` && |\n| &&
` <CHECKFIELD>MANDT</CHECKFIELD>` && |\n| &&
` <PRIMPOS>0001</PRIMPOS>` && |\n| &&
` <DOMNAME>MANDT</DOMNAME>` && |\n| &&
` <DATATYPE>CLNT</DATATYPE>` && |\n| &&
` </DD05M>` && |\n| &&
` <DD05M>` && |\n| &&
` <FIELDNAME>MWAER</FIELDNAME>` && |\n| &&
` <FORTABLE>T000</FORTABLE>` && |\n| &&
` <FORKEY>MWAER</FORKEY>` && |\n| &&
` <CHECKTABLE>TCURC</CHECKTABLE>` && |\n| &&
` <CHECKFIELD>WAERS</CHECKFIELD>` && |\n| &&
` <PRIMPOS>0002</PRIMPOS>` && |\n| &&
` <DOMNAME>WAERS</DOMNAME>` && |\n| &&
` <DATATYPE>CUKY</DATATYPE>` && |\n| &&
` </DD05M>` && |\n| &&
` </DD05M_TABLE>` && |\n| &&
` <DD08V_TABLE>` && |\n| &&
` <DD08V>` && |\n| &&
` <FIELDNAME>LOGSYS</FIELDNAME>` && |\n| &&
` <CHECKTABLE>TBDLS</CHECKTABLE>` && |\n| &&
` <FRKART>KEY</FRKART>` && |\n| &&
` <CARD>1</CARD>` && |\n| &&
` <DDTEXT>Logical system</DDTEXT>` && |\n| &&
` <CARDLEFT>C</CARDLEFT>` && |\n| &&
` </DD08V>` && |\n| &&
` <DD08V>` && |\n| &&
` <FIELDNAME>MWAER</FIELDNAME>` && |\n| &&
` <CHECKTABLE>TCURC</CHECKTABLE>` && |\n| &&
` <FRKART>KEY</FRKART>` && |\n| &&
` <CARD>N</CARD>` && |\n| &&
` <CARDLEFT>1</CARDLEFT>` && |\n| &&
` </DD08V>` && |\n| &&
` </DD08V_TABLE>` && |\n| &&
` <DD35V_TALE>` && |\n| &&
` <DD35V>` && |\n| &&
` <SHLPNAME>H_T000</SHLPNAME>` && |\n| &&
` </DD35V>` && |\n| &&
` </DD35V_TALE>` && |\n| &&
` <DD36M>` && |\n| &&
` <DD36M>` && |\n| &&
` <SHLPNAME>H_T000</SHLPNAME>` && |\n| &&
` <SHLPFIELD>MANDT</SHLPFIELD>` && |\n| &&
` <FLPOSITION>0001</FLPOSITION>` && |\n| &&
` <SHTABLE>T000</SHTABLE>` && |\n| &&
` <SHFIELD>MANDT</SHFIELD>` && |\n| &&
` <SHLPINPUT>X</SHLPINPUT>` && |\n| &&
` <SHLPOUTPUT>X</SHLPOUTPUT>` && |\n| &&
` <ROLLNAME>MANDT</ROLLNAME>` && |\n| &&
` <DOMNAME>MANDT</DOMNAME>` && |\n| &&
` <DATATYPE>CLNT</DATATYPE>` && |\n| &&
` <LENG>000003</LENG>` && |\n| &&
` </DD36M>` && |\n| &&
` <DD36M>` && |\n| &&
` <SHLPNAME>H_T000</SHLPNAME>` && |\n| &&
` <SHLPFIELD>MTEXT</SHLPFIELD>` && |\n| &&
` <FLPOSITION>0002</FLPOSITION>` && |\n| &&
` <SHTYPE>G</SHTYPE>` && |\n| &&
` <SHLPOUTPUT>X</SHLPOUTPUT>` && |\n| &&
` <ROLLNAME>MTEXT_D</ROLLNAME>` && |\n| &&
` <DOMNAME>TEXT25</DOMNAME>` && |\n| &&
` <DATATYPE>CHAR</DATATYPE>` && |\n| &&
` <LENG>000025</LENG>` && |\n| &&
` </DD36M>` && |\n| &&
` <DD36M>` && |\n| &&
` <SHLPNAME>H_T000</SHLPNAME>` && |\n| &&
` <SHLPFIELD>ORT01</SHLPFIELD>` && |\n| &&
` <FLPOSITION>0003</FLPOSITION>` && |\n| &&
` <SHTYPE>G</SHTYPE>` && |\n| &&
` <SHLPOUTPUT>X</SHLPOUTPUT>` && |\n| &&
` <ROLLNAME>ORT01</ROLLNAME>` && |\n| &&
` <DOMNAME>TEXT25</DOMNAME>` && |\n| &&
` <DATATYPE>CHAR</DATATYPE>` && |\n| &&
` <LENG>000025</LENG>` && |\n| &&
` </DD36M>` && |\n| &&
` </DD36M>` && |\n| &&
` <TABL_EXTRAS>` && |\n| &&
` <TDDAT>` && |\n| &&
` <TABNAME>T000</TABNAME>` && |\n| &&
` <CCLASS>SS</CCLASS>` && |\n| &&
` </TDDAT>` && |\n| &&
` </TABL_EXTRAS>` && |\n| &&
` </asx:values>` && |\n| &&
` </asx:abap>`.
test( iv_xml = lv_xml
iv_ddl = lv_ddl ).
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_ABAPGIT_OBJECT_TABL_DDL</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>abapGit - TABL DDL</DESCRIPT>
<STATE>1</STATE>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -1,11 +1,12 @@
{ {
"input_folder": "{src,deps}", "input_folder": "{src,deps}",
"input_filter": [ "input_filter": [
"deps/",
"\\.w3mi.", "\\.w3mi.",
"deps/",
"src/ui/zcl_abapgit_e", "src/ui/zcl_abapgit_e",
"src/zcl_abapgit_e",
"src/utils/*", "src/utils/*",
"src/zcl_abapgit_e",
"zag1",
"src/env/*", "src/env/*",
"zcl_abapgit_adt_link", "zcl_abapgit_adt_link",
"zcl_abapgit_aff_registry", "zcl_abapgit_aff_registry",
@ -15,6 +16,7 @@
"zcl_abapgit_b", "zcl_abapgit_b",
"zcl_abapgit_c", "zcl_abapgit_c",
"zcl_abapgit_d", "zcl_abapgit_d",
"zcl_abapgit_exit",
"zcl_abapgit_f", "zcl_abapgit_f",
"zcl_abapgit_g", "zcl_abapgit_g",
"zcl_abapgit_h", "zcl_abapgit_h",
@ -22,15 +24,15 @@
"zcl_abapgit_j", "zcl_abapgit_j",
"zcl_abapgit_l", "zcl_abapgit_l",
"zcl_abapgit_n", "zcl_abapgit_n",
"zcl_abapgit_exit",
"zcl_abapgit_object_intf",
"zcl_abapgit_object_devc", "zcl_abapgit_object_devc",
"zcl_abapgit_object_intf",
"zcl_abapgit_object_zag",
"zcl_abapgit_objects_bridge",
"zcl_abapgit_objects_files", "zcl_abapgit_objects_files",
"zcl_abapgit_objects_program", "zcl_abapgit_objects_program",
"zcl_abapgit_objects_super", "zcl_abapgit_objects_super",
"zcl_abapgit_objects.clas.abap", "zcl_abapgit_objects.clas.abap",
"zcl_abapgit_objects.clas.testclasses.abap", "zcl_abapgit_objects.clas.testclasses.abap",
"zcl_abapgit_objects_bridge",
"zcl_abapgit_oo_base", "zcl_abapgit_oo_base",
"zcl_abapgit_oo_factory", "zcl_abapgit_oo_factory",
"zcl_abapgit_oo_interface", "zcl_abapgit_oo_interface",
@ -54,6 +56,7 @@
"zif_abapgit_l", "zif_abapgit_l",
"zif_abapgit_m", "zif_abapgit_m",
"zif_abapgit_object", "zif_abapgit_object",
"zcl_abapgit_object_tabl_ddl",
"zif_abapgit_oo_object_fnc", "zif_abapgit_oo_object_fnc",
"zif_abapgit_p", "zif_abapgit_p",
"zif_abapgit_r", "zif_abapgit_r",