SAP / abap-file-formats

File formats that define and specify the file representation for ABAP development objects
MIT License
58 stars 56 forks source link

Using ENUMS #92

Closed larshp closed 3 years ago

larshp commented 3 years ago

Hi, I have not used enums very much, so I looked into how it works,

https://blogs.sap.com/2016/10/10/abap-news-release-7.51-enumerations/

notably "Normally, you are not interested in the contents of an enumerated object at all."

in abap-file-formats we are interested in the values, eg setting a json value,

TYPES:
  basetype TYPE c LENGTH 1,
  BEGIN OF ENUM ver BASE TYPE basetype,
    standard          VALUE IS INITIAL,
    cloud_development VALUE '5',
  END OF ENUM ver.

DATA: BEGIN OF ls_json,
        ver TYPE basetype,
      END OF ls_json.
ls_json-ver = cloud_development.
WRITE ls_json-ver.

Which outputs "C" when run

As we are interested in values, probably using structured constants is the better approach?

larshp commented 3 years ago

or are we interested in having both internal and external values accessible to ABAP,

CONSTANTS:
  BEGIN OF abap_language_version,
    BEGIN OF standard,
      internal TYPE string VALUE '',
      external TYPE string VALUE 'standard',
    END OF standard,
    BEGIN OF standard_unicode,
      internal TYPE string VALUE 'X',
      external TYPE string VALUE 'standardUnicode',
    END OF standard_unicode,
    BEGIN OF cloud_development,
      internal TYPE string VALUE '5',
      external TYPE string VALUE 'cloudDevelopment',
    END OF cloud_development,
  END OF abap_language_version.
larshp commented 3 years ago

@schneidermic0 any thoughts? we need to decide this to move forward

schneidermic0 commented 3 years ago

I understood our current approach the following way:

For fields with only specific values we define a type referring to the enum. In the enum we specify all possible options as enumeration constants (in the example above: standard and cloud_development). From the enumeration constants we can derive the values for JSON schema (e.g. standard and cloudDevelopment) by transforming the enumeration constants to camel-case values. The enumeration values (like the initial value and 5) can be used in ABAP and represent the internal values of the domain-specific data models (e.g., cloudDevelopment is stored as 5 in the database). It is not shown in JSON schema, but can be used in the transformation.

I think the enums would help to link the field to its possible values. I think it is also fine to define the enumeration values with the internal values. Most probably, I would prefer to add also the structure extension to use the values in ABAP.

But I think we have to reiterate over the following aspects:

  1. We have to define an initial value. Most probably this is not always an allowed value in today's data models
  2. The values are restricted to 16 bytes (i.e., character fields can store 8 characters). Should be sufficient for almost all use cases, but there might be limitations
  3. Using the enumeration values in ABAP would require conversions.

If we would use structured constants instead: Do you have any idea how we would link the possible values to the actual fields. Do you see any way except link it in ABAP Doc or using naming conventions?

larshp commented 3 years ago

something like this, note that the values are linked via the TYPE

TYPES category_internal TYPE n LENGTH 2.
TYPES category_external TYPE string.

CONSTANTS: BEGIN OF category_internal,
             classic_badi_int TYPE category_internal VALUE '01',
           END OF category_internal.
CONSTANTS: BEGIN OF category_external,
             classic_badi_ext TYPE category_external VALUE 'something',
           END OF category_external.

DATA lv_json TYPE category_external.

******************************************************
** BELOW IS CURRENTLY OUT OF SCOPE FOR FILE FORMATS **
******************************************************

DATA ls_seoclassdf TYPE seoclassdf.

******** SERIALIZATION
IF ls_seoclassdf-category = category_internal-classic_badi_int.
  lv_json = category_external-classic_badi_ext.
ENDIF.

******** DESERIALIZATION
IF lv_json = category_external-classic_badi_ext.
  ls_seoclassdf-category = category_internal-classic_badi_int.
ENDIF.
schneidermic0 commented 3 years ago

Unfortunately, we cannot use the same name for the constants and the types. This will lead to syntax errors in interface definition.

If we went for constants, it would be something like this:

  TYPES ty_category TYPE c LENGTH 2.

  CONSTANTS: BEGIN OF co_category,
               general      TYPE ty_category VALUE '00',
               classic_badi TYPE ty_category VALUE '01',
             END OF co_category.

  TYPES category TYPE ty_category.

I have used only one group of constants, because I didn't added the external value. The external name could be retrieved from general -> general or classic_badi -> classicBadi(e.g. in a simple transformation), couldn't it?

larshp commented 3 years ago

@schneidermic0 yep, looks good to me

larshp commented 3 years ago

example implemented in https://github.com/SAP/abap-file-formats/pull/95

schneidermic0 commented 3 years ago

Thanks @larshp for your proposal. The team checks whether they can link the constant to the type.

schneidermic0 commented 3 years ago

We discussed this with several colleagues and also @larshp.

We cannot overcome the disadvantages I mentioned above if we were using enums. Especially the conversion to the real values which are stored in the database would be ugly.

Therefore, we came to the conclusion to not use enums, but constants. One option would be to link the constants for a type with an annotation in ABAP doc (see example below with annotation $enumValues):

  "! Description of TY_CATEGORY
  "! $enumValues: co_category
  TYPES ty_category TYPE c LENGTH 2.

  CONSTANTS: BEGIN OF co_category,
               "! Description of category 'general'
               general      TYPE ty_category VALUE '00',
               "! Description of category 'classic_badi'
               classic_badi TYPE ty_category VALUE '01',
             END OF co_category.

  TYPES category TYPE ty_category.

We will update #95 accordingly.