From c0b3b9d2448fb9dcdf243dd023995129ed1c4557 Mon Sep 17 00:00:00 2001 From: danrega <16720986+danrega@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:28:58 +0100 Subject: [PATCH] Update --- 03_ABAP_SQL.md | 8 +- 07_String_Processing.md | 56 ++++++++- 22_Misc_ABAP_Classes.md | 254 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 312 insertions(+), 6 deletions(-) diff --git a/03_ABAP_SQL.md b/03_ABAP_SQL.md index 9fb222d..3eac490 100644 --- a/03_ABAP_SQL.md +++ b/03_ABAP_SQL.md @@ -352,7 +352,7 @@ SELECT ds~col1, ds~col2, ds~col3
-**Reading data from a database table in another client** ([classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm) only ). Note that there are several variants of the `USING ...` addition for switching the [implicit client handling (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_sql_client_handling.htm) from the current client to other clients. See more information [here (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapselect_client.htm). +**Reading data from a database table in another client** ([classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm) only). Note that there are several variants of the `USING ...` addition for switching the [implicit client handling (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_sql_client_handling.htm) from the current client to other clients. See more information [here (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapselect_client.htm). ``` abap "Some examples; not available in ABAP for Cloud Development @@ -985,10 +985,10 @@ INTO @DATA(more_sql_expr). How [window expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_expression_glosry.htm "Glossary Entry") work: -- Defines a subset of the result set (i. e. the +- Define a subset of the result set (i. e. the "[window](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_glosry.htm "Glossary Entry")") of a database query that implements ABAP SQL -- Applies a [window +- Apply a [window function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_function_glosry.htm "Glossary Entry") - which evaluates the rows of the window and which can, for example, be an [aggregate @@ -1147,7 +1147,7 @@ SELECT * AND comp11 IS INITIAL "Combination of logical expression using AND, OR and parentheses - AND ( comp12 = a AND comp13 < b ) OR ( comp14 > c AND comp15 <> d ) + AND ( comp12 = a AND comp13 < b ) OR ( comp14 > c AND comp15 <> d ) INTO TABLE @DATA(itab_where). ``` diff --git a/07_String_Processing.md b/07_String_Processing.md index abc5646..f609d49 100644 --- a/07_String_Processing.md +++ b/07_String_Processing.md @@ -28,6 +28,8 @@ - [More String Functions](#more-string-functions) - [Checking the Similarity of Strings](#checking-the-similarity-of-strings) - [Repeating Strings](#repeating-strings) + - [Returning the Smallest/Biggest of a Set of Character-Like Arguments](#returning-the-smallestbiggest-of-a-set-of-character-like-arguments) + - [Escaping Special Characters](#escaping-special-characters) - [Executable Example](#executable-example) @@ -364,7 +366,7 @@ s1 = |{ utc XSD = YES }|. "2024-01-01T13:51:38.57088Z "STYLE: Defining the style of decimal floating point numbers; "see the details in the ABAP Keyword Documentation. DATA(dcfl34) = CONV decfloat34( '-123.45600' ). -s1 = |{ dcfl34 }|. "-123.456out->write( s1 ). +s1 = |{ dcfl34 }|. "-123.456 "Creates the predefined format s1 = |{ dcfl34 STYLE = SIMPLE }|. "-123.456 "+/- added to the right, removes trailing zeros @@ -1791,6 +1793,58 @@ ENDTRY. +### Returning the Smallest/Biggest of a Set of Character-Like Arguments +- [`cmin/cmax`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencmax_cmin_functions.htm) returns a string that contains the content of the smallest or biggest of a set of character-like arguments +- 'Set' means at least two arguments and a maximum of nine argeuments are passed (`valn` operators) for comparison. +- The comparison is made from left to right, and the first different character found determines the smaller or bigger argument. + +```abap +DATA(min) = cmin( val1 = `zzzzzzz` + val2 = `zzazzzzzzzz` "smallest argument + val3 = `zzzzabc` ). + +DATA(max) = cmax( val1 = `abcdef` "biggest argument + val2 = `aaghij` + val3 = `aaaaklmn` + val4 = `aaaaaaopqrs` + val5 = `aaaaaaaaaatuvwxy` + val6 = `aaaaaaaaaaaaaz` ). +``` + + + +### Escaping Special Characters +- [`escape`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenescape_functions.htm) returns a string that is provided for the `val` parameter by escaping special characters according to the specification in the `format` parameter. +- Suitable values for the `format` parameter (which expects a data object of type `i`) are available in the `CL_ABAP_FORMAT` class (the constants starting with `E_`). +- Special rules apply to different contexts, such as URLS and JSON. Also note the prevention of Cross Site Scripting (XSS) attacks on web applications. For more information, refer to the [documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenescape_functions.htm). + +```abap +"Context: URLs +DATA(esc1) = escape( val = '...test: 5@8...' + format = cl_abap_format=>e_url_full ). +"...test%3A%205%408... + +"Context: JSON +DATA(esc2) = escape( val = 'some "test" json \ with backslash and double quotes' + format = cl_abap_format=>e_json_string ). +"some \"test\" json \\ with backslash and double quotes + + +"Context: String templates +DATA(esc3) = escape( val = 'Special characters in string templates: |, \, {, }' + format = cl_abap_format=>e_string_tpl ). +"Special characters in string templates: \|, \\, \{, \} + +"Invalid value for the format parameter +TRY. + DATA(esc4) = escape( val = 'This will raise an exception due to an invalid format value.' + format = 123 ). + CATCH cx_sy_strg_par_val. +ENDTRY. +``` + + + ## Executable Example [zcl_demo_abap_string_proc](./src/zcl_demo_abap_string_proc.clas.abap) diff --git a/22_Misc_ABAP_Classes.md b/22_Misc_ABAP_Classes.md index 0d1d6d1..6f192f6 100644 --- a/22_Misc_ABAP_Classes.md +++ b/22_Misc_ABAP_Classes.md @@ -26,6 +26,7 @@ - [Application Log](#application-log) - [Running Code in the Background](#running-code-in-the-background) - [Locking](#locking) + - [Calling Services](#calling-services) This ABAP cheat sheet contains a selection of available ABAP classes, serving as a quick introduction, along with code snippets to explore the functionality in action. @@ -603,7 +604,7 @@ DATA(str_no_blanks) = CONV string( chars ).CL_ABAP_CONV_CODEPAGE CL_ABAP_CONV_CODEPAGEXCO_CP | Class | Details/Code Snippet | +
CL_WEB_HTTP_CLIENT_MANAGERCL_HTTP_DESTINATION_PROVIDER |
+
+
+ +``` abap +CLASS zcl_some_class DEFINITION PUBLIC FINAL CREATE PUBLIC. + PUBLIC SECTION. + INTERFACES if_oo_adt_classrun. + PRIVATE SECTION. + CONSTANTS url_cs TYPE string VALUE `https://api.github.com/repos/SAP-samples/abap-cheat-sheets/git/trees/main`. + CONSTANTS url_gh TYPE string VALUE `https://raw.githubusercontent.com/SAP-samples/abap-cheat-sheets/main/`. + CONSTANTS url_api TYPE string VALUE `https://api.github.com/markdown`. + DATA url TYPE string. + TYPES: BEGIN OF s, + file_name TYPE string, + title TYPE string, + code_snippets TYPE string_table, + error TYPE abap_bool, + END OF s. + DATA tab TYPE TABLE OF s WITH EMPTY KEY. + DATA snippets TYPE string_table. + DATA html TYPE string. +ENDCLASS. +CLASS zcl_some_class IMPLEMENTATION. + METHOD if_oo_adt_classrun~main. + TRY. + "Creating a client object using a destination + "In the example, the HTTP destination is created using a plain URL. + "Here, a GitHub API is used to retrieve file names of the ABAP cheat sheet repository. + DATA(http_client) = cl_web_http_client_manager=>create_by_http_destination( i_destination = cl_http_destination_provider=>create_by_url( i_url = url_cs ) ). + "Sending an HTTP GET request and returning the response + "In the example, the HTTP body is retrieved as string data. + DATA(response) = http_client->execute( if_web_http_client=>get )->get_text( ). + CATCH cx_root INTO DATA(err). + out->write( err->get_text( ) ). + ENDTRY. + IF err IS INITIAL. + "Markdown file names are contained in the returned string in a specific + "pattern. In the following code, the markdown file names are extracted + "using a regular expression (pattern: "path":"04_ABAP_Object_Orientation.md") + "After '"path":"' (not including this part, indivated by \K), two + "digits must follow. Then, the further file name is captured with a + "non-greedy capturing up to '.md'. + FIND ALL OCCURRENCES OF PCRE `("path":")\K\d\d.*?\.md` IN response + RESULTS DATA(results) + IGNORING CASE. + + "The 'results' internal table contains all findings and includes their + "offset and length information. + "Using a loop, the actual file names are extracted from the 'response' + "string and added to an internal table that is to receive more information + "in the code below. + LOOP AT results REFERENCE INTO DATA(md). + tab = VALUE #( BASE tab ( file_name = substring( val = response off = md->offset len = md->length ) ) ). + ENDLOOP. + SORT tab BY file_name ASCENDING. + + "In the following loop, the raw markdown content is retrieved using an HTTP GET request, also + "by creating a client object and using a destination (another plain URL). The URL is constructed + "using the constant value plus the markdown file that was retreived before. + LOOP AT tab REFERENCE INTO DATA(cs). + url = url_gh && cs->file_name. + TRY. + http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = cl_http_destination_provider=>create_by_url( i_url = url ) ). + DATA(raw_md) = http_client->execute( if_web_http_client=>get )->get_text( ). + "Putting the long string that was retrieved in an internal table of type string + "for further processing (extracting the code snippets). + SPLIT raw_md AT |\n| INTO TABLE snippets. + DATA(flag) = ''. + "In the loop, all content from the markdown that is not part of a code + "snippet (indicated by the triple ```) is deleted. + "The replacements with dummy content in the loop are only done so that + "the POST request further down can work with the provided content + "(i.e. avoiding issues characters such as "; they are inserted later again). + LOOP AT snippets REFERENCE INTO DATA(line). + DATA(tabix) = sy-tabix. + FIND PCRE '^\s*```' IN line->*. + IF sy-subrc = 0 AND flag = ''. + line->* = `%%%--START--%%%%`. + flag = 'X'. + ELSEIF sy-subrc = 0 AND flag = 'X'. + line->* = `%%%--END--%%%%`. + flag = ''. + ELSEIF flag <> 'X'. + DELETE snippets INDEX tabix. + ELSE. + FIND PCRE `^\s*"` IN line->*. + IF sy-subrc = 0. + DATA(comment1) = 'X'. + ENDIF. + FIND PCRE `^\*` IN line->*. + IF sy-subrc = 0. + DATA(comment2) = 'X'. + ENDIF. + FIND `***********************************************************************` + IN line->*. + IF sy-subrc = 0. + DATA(divider) = 'X'. + ENDIF. + IF comment1 = 'X' OR comment2 = 'X' OR divider = 'X'. + DELETE snippets INDEX tabix. + CLEAR: comment1, comment2, divider. + ELSE. + REPLACE ALL OCCURRENCES OF `"` IN line->* WITH `§§§§§`. + REPLACE ALL OCCURRENCES OF `\` IN line->* WITH `%%%%%`. + ENDIF. + ENDIF. + ENDLOOP. + "Adding the code snippets to the information table + cs->code_snippets = snippets. + CLEAR snippets. + CATCH cx_root INTO err. + cs->error = abap_true. + ENDTRY. + DELETE ADJACENT DUPLICATES FROM cs->code_snippets COMPARING table_line. + ENDLOOP. + "Creating the final html to be displayed + LOOP AT tab REFERENCE INTO cs WHERE code_snippets IS NOT INITIAL AND error = abap_false. + LOOP AT cs->code_snippets REFERENCE INTO DATA(code). + tabix = sy-tabix. + IF code->* = `%%%--START--%%%%`. + code->* = |```|. + ENDIF. + IF code->* = `%%%--END--%%%%`. + code->* = |```|. + INSERT `*****************` && |\\n| + INTO cs->code_snippets INDEX tabix + 1. + ENDIF. + code->* = code->* && |\\n|. + ENDLOOP. + "For the POST request, concatenating the string table to a single string. + DATA(code_string) = concat_lines_of( table = cs->code_snippets ). + TRY. + "Another creation of a client object using a destination + "This example deals with a POST request. + http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = cl_http_destination_provider=>create_by_url( i_url = url_api ) ). + DATA(request) = http_client->get_http_request( ). + request->set_text( `{"text":"` && code_string && `"}` ). + request->set_header_fields( VALUE #( ( name = 'Accept' value = 'application/vnd.github+json' ) ) ). + DATA(post) = http_client->execute( if_web_http_client=>post ). + DATA(status) = post->get_status( ). + IF status-code <> 200. + cs->error = abap_true. + DATA(status_error) = |Post request error: { status-code } / { status-reason }|. + ELSE. + "Retrieving the created html code + DATA(html_code) = post->get_text( ). + REPLACE ALL OCCURRENCES OF `§§§§§` IN html_code WITH `"`. + REPLACE ALL OCCURRENCES OF `%%%%%` IN html_code WITH `\`. + REPLACE ALL OCCURRENCES OF PCRE `( )(\w.*)` IN html_code WITH `$1 $2`.
+ ENDIF.
+ CATCH cx_root INTO DATA(error).
+ cs->error = abap_true.
+ ENDTRY.
+ "Preparing the title for expandable sections
+ DATA(title) = cs->file_name.
+ REPLACE ALL OCCURRENCES OF `_` IN title WITH ` `.
+ REPLACE PCRE `^..` IN title WITH ``.
+ REPLACE `.md` IN title WITH ``.
+ "Assembling expandable sections
+ html = html &&
+ ` |
+