@linkup-ai/abap-ai 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +384 -0
  2. package/dist/adt-client.js +364 -0
  3. package/dist/cli/activate.js +113 -0
  4. package/dist/cli/init.js +333 -0
  5. package/dist/cli/remove.js +80 -0
  6. package/dist/cli/status.js +229 -0
  7. package/dist/cli/systems.js +68 -0
  8. package/dist/cli.js +81 -0
  9. package/dist/index.js +1318 -0
  10. package/dist/knowledge/abap/abap-dictionary.md +199 -0
  11. package/dist/knowledge/abap/abap-sql.md +296 -0
  12. package/dist/knowledge/abap/amdp.md +273 -0
  13. package/dist/knowledge/abap/clean-code.md +293 -0
  14. package/dist/knowledge/abap/cloud-background-processing.md +250 -0
  15. package/dist/knowledge/abap/cloud-communication.md +265 -0
  16. package/dist/knowledge/abap/cloud-development.md +176 -0
  17. package/dist/knowledge/abap/cloud-extensibility.md +252 -0
  18. package/dist/knowledge/abap/cloud-released-apis.md +261 -0
  19. package/dist/knowledge/abap/constructor-expressions.md +289 -0
  20. package/dist/knowledge/abap/enhancements.md +232 -0
  21. package/dist/knowledge/abap/exceptions.md +271 -0
  22. package/dist/knowledge/abap/internal-tables.md +205 -0
  23. package/dist/knowledge/abap/object-orientation.md +298 -0
  24. package/dist/knowledge/abap/performance.md +216 -0
  25. package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
  26. package/dist/knowledge/abap/rap-business-events.md +216 -0
  27. package/dist/knowledge/abap/rap-draft.md +191 -0
  28. package/dist/knowledge/abap/rap-eml.md +453 -0
  29. package/dist/knowledge/abap/rap-end-to-end.md +486 -0
  30. package/dist/knowledge/abap/rap-feature-control.md +185 -0
  31. package/dist/knowledge/abap/rap-numbering.md +280 -0
  32. package/dist/knowledge/abap/rap-service-exposure.md +163 -0
  33. package/dist/knowledge/abap/rap-unmanaged.md +468 -0
  34. package/dist/knowledge/abap/string-processing.md +180 -0
  35. package/dist/knowledge/abap/unit-testing.md +303 -0
  36. package/dist/knowledge/abap-cds/access-control.md +241 -0
  37. package/dist/knowledge/abap-cds/annotations.md +331 -0
  38. package/dist/knowledge/abap-cds/associations.md +254 -0
  39. package/dist/knowledge/abap-cds/expressions.md +230 -0
  40. package/dist/knowledge/abap-cds/functions.md +245 -0
  41. package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
  42. package/dist/knowledge/cap/authentication.md +278 -0
  43. package/dist/knowledge/cap/cdl-syntax.md +247 -0
  44. package/dist/knowledge/cap/cql-queries.md +266 -0
  45. package/dist/knowledge/cap/deployment.md +343 -0
  46. package/dist/knowledge/cap/event-handlers.md +287 -0
  47. package/dist/knowledge/cap/fiori-integration.md +303 -0
  48. package/dist/knowledge/cap/service-definitions.md +287 -0
  49. package/dist/knowledge/fiori/annotations.md +347 -0
  50. package/dist/knowledge/fiori/deployment.md +340 -0
  51. package/dist/knowledge/fiori/fiori-elements.md +332 -0
  52. package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
  53. package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
  54. package/dist/knowledge/fiori/ui5-controllers.md +358 -0
  55. package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
  56. package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
  57. package/dist/knowledge/fiori/ui5-manifest.md +411 -0
  58. package/dist/knowledge/fiori/ui5-routing.md +303 -0
  59. package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
  60. package/dist/logger.js +114 -0
  61. package/dist/system-profile.js +207 -0
  62. package/dist/tools/abap-doc.js +72 -0
  63. package/dist/tools/abapgit.js +161 -0
  64. package/dist/tools/activate.js +68 -0
  65. package/dist/tools/atc-check.js +117 -0
  66. package/dist/tools/auth-object.js +56 -0
  67. package/dist/tools/breakpoints.js +76 -0
  68. package/dist/tools/call-hierarchy.js +84 -0
  69. package/dist/tools/cds-annotations.js +98 -0
  70. package/dist/tools/cds-dependencies.js +65 -0
  71. package/dist/tools/check.js +47 -0
  72. package/dist/tools/code-completion.js +70 -0
  73. package/dist/tools/code-coverage.js +111 -0
  74. package/dist/tools/create-amdp.js +111 -0
  75. package/dist/tools/create-dcl.js +81 -0
  76. package/dist/tools/create-transport.js +38 -0
  77. package/dist/tools/create.js +285 -0
  78. package/dist/tools/data-preview.js +37 -0
  79. package/dist/tools/delete.js +45 -0
  80. package/dist/tools/deploy-bsp.js +298 -0
  81. package/dist/tools/discovery.js +59 -0
  82. package/dist/tools/element-info.js +93 -0
  83. package/dist/tools/enhancements.js +186 -0
  84. package/dist/tools/extract-method.js +44 -0
  85. package/dist/tools/function-group.js +59 -0
  86. package/dist/tools/knowledge.js +275 -0
  87. package/dist/tools/lock-object.js +75 -0
  88. package/dist/tools/message-class.js +67 -0
  89. package/dist/tools/navigate.js +80 -0
  90. package/dist/tools/number-range.js +57 -0
  91. package/dist/tools/object-documentation.js +43 -0
  92. package/dist/tools/object-structure.js +78 -0
  93. package/dist/tools/object-versions.js +57 -0
  94. package/dist/tools/package-contents.js +60 -0
  95. package/dist/tools/pretty-printer.js +35 -0
  96. package/dist/tools/publish-binding.js +49 -0
  97. package/dist/tools/quick-fix.js +69 -0
  98. package/dist/tools/read.js +167 -0
  99. package/dist/tools/refactor-rename.js +60 -0
  100. package/dist/tools/release-transport.js +24 -0
  101. package/dist/tools/released-apis.js +51 -0
  102. package/dist/tools/repository-tree.js +90 -0
  103. package/dist/tools/scaffold-rap.js +642 -0
  104. package/dist/tools/search.js +73 -0
  105. package/dist/tools/shared/data-format.js +101 -0
  106. package/dist/tools/sql-console.js +17 -0
  107. package/dist/tools/system-info.js +270 -0
  108. package/dist/tools/traces.js +66 -0
  109. package/dist/tools/transport-contents.js +83 -0
  110. package/dist/tools/transports.js +67 -0
  111. package/dist/tools/unit-test.js +135 -0
  112. package/dist/tools/where-used.js +59 -0
  113. package/dist/tools/write.js +101 -0
  114. package/package.json +49 -0
@@ -0,0 +1,298 @@
1
+ # Object Orientation — classes, interfaces, inheritance, events
2
+
3
+ ## Class Definition
4
+
5
+ ```abap
6
+ CLASS zcl_order_processor DEFINITION
7
+ PUBLIC FINAL CREATE PUBLIC.
8
+
9
+ PUBLIC SECTION.
10
+ TYPES: ty_order_id TYPE char10.
11
+ CONSTANTS: c_max_items TYPE i VALUE 999.
12
+
13
+ METHODS:
14
+ constructor IMPORTING iv_order_id TYPE ty_order_id,
15
+ process IMPORTING iv_input TYPE string
16
+ RETURNING VALUE(rv_result) TYPE string
17
+ RAISING zcx_order_error,
18
+ get_id RETURNING VALUE(rv_id) TYPE ty_order_id.
19
+
20
+ CLASS-METHODS:
21
+ factory IMPORTING iv_id TYPE ty_order_id
22
+ RETURNING VALUE(ro_inst) TYPE REF TO zcl_order_processor.
23
+
24
+ PROTECTED SECTION.
25
+ DATA mv_status TYPE char1.
26
+ METHODS validate.
27
+
28
+ PRIVATE SECTION.
29
+ DATA mv_order_id TYPE ty_order_id.
30
+ METHODS helper.
31
+
32
+ ENDCLASS.
33
+
34
+ CLASS zcl_order_processor IMPLEMENTATION.
35
+
36
+ METHOD constructor.
37
+ mv_order_id = iv_order_id.
38
+ ENDMETHOD.
39
+
40
+ METHOD process.
41
+ rv_result = |Processed: { iv_input }|.
42
+ ENDMETHOD.
43
+
44
+ METHOD get_id.
45
+ rv_id = mv_order_id.
46
+ ENDMETHOD.
47
+
48
+ METHOD factory.
49
+ ro_inst = NEW #( iv_id ).
50
+ ENDMETHOD.
51
+
52
+ METHOD validate.
53
+ ENDMETHOD.
54
+
55
+ METHOD helper.
56
+ ENDMETHOD.
57
+
58
+ ENDCLASS.
59
+ ```
60
+
61
+ ## Visibility
62
+
63
+ | Modifier | Class | Subclass | External |
64
+ |---|---|---|---|
65
+ | PUBLIC | Yes | Yes | Yes |
66
+ | PROTECTED | Yes | Yes | No |
67
+ | PRIVATE | Yes | No | No |
68
+
69
+ ## Instantiation Control
70
+
71
+ ```abap
72
+ CREATE PUBLIC " Anyone can instantiate
73
+ CREATE PROTECTED " Only class + subclasses
74
+ CREATE PRIVATE " Only within the class (use factory)
75
+ ```
76
+
77
+ ## Object Creation
78
+
79
+ ```abap
80
+ " NEW operator — preferred
81
+ DATA(zo_proc) = NEW zcl_order_processor( iv_order_id = '1000' ).
82
+
83
+ " Inline chain
84
+ DATA(lv_result) = NEW zcl_order_processor( '1000' )->process( `data` ).
85
+
86
+ " Factory method
87
+ DATA(zo_inst) = zcl_order_processor=>factory( '1000' ).
88
+
89
+ " Static method call
90
+ zcl_utility=>execute( ).
91
+ ```
92
+
93
+ ## Method Signatures
94
+
95
+ ```abap
96
+ METHODS process
97
+ IMPORTING iv_required TYPE string
98
+ iv_optional TYPE string OPTIONAL
99
+ iv_default TYPE i DEFAULT 10
100
+ EXPORTING ev_output TYPE string
101
+ CHANGING cv_data TYPE string
102
+ RETURNING VALUE(rv_result) TYPE string
103
+ RAISING zcx_my_exception.
104
+ ```
105
+
106
+ ## Interfaces
107
+
108
+ ```abap
109
+ INTERFACE zif_processable PUBLIC.
110
+ TYPES ty_result TYPE string.
111
+ METHODS:
112
+ process IMPORTING iv_input TYPE string
113
+ RETURNING VALUE(rv_result) TYPE ty_result,
114
+ get_status RETURNING VALUE(rv_status) TYPE char1.
115
+ ENDINTERFACE.
116
+
117
+ CLASS zcl_impl DEFINITION PUBLIC FINAL CREATE PUBLIC.
118
+ PUBLIC SECTION.
119
+ INTERFACES zif_processable.
120
+ ALIASES process FOR zif_processable~process.
121
+ ALIASES get_status FOR zif_processable~get_status.
122
+ ENDCLASS.
123
+
124
+ CLASS zcl_impl IMPLEMENTATION.
125
+ METHOD zif_processable~process.
126
+ rv_result = |Done: { iv_input }|.
127
+ ENDMETHOD.
128
+ METHOD zif_processable~get_status.
129
+ rv_status = 'A'.
130
+ ENDMETHOD.
131
+ ENDCLASS.
132
+ ```
133
+
134
+ ## Interface Usage + Polymorphism
135
+
136
+ ```abap
137
+ " Program to interface, not implementation
138
+ DATA zo_proc TYPE REF TO zif_processable.
139
+ zo_proc = NEW zcl_impl_a( ).
140
+ zo_proc->process( `input` ). " Calls zcl_impl_a
141
+
142
+ zo_proc = NEW zcl_impl_b( ).
143
+ zo_proc->process( `input` ). " Calls zcl_impl_b
144
+ ```
145
+
146
+ ## Interface Inheritance
147
+
148
+ ```abap
149
+ INTERFACE zif_extended PUBLIC.
150
+ INTERFACES zif_processable.
151
+ METHODS extended_method.
152
+ ENDINTERFACE.
153
+ ```
154
+
155
+ ## Inheritance
156
+
157
+ ```abap
158
+ CLASS zcl_child DEFINITION
159
+ INHERITING FROM zcl_parent
160
+ PUBLIC FINAL CREATE PUBLIC.
161
+
162
+ PUBLIC SECTION.
163
+ METHODS constructor IMPORTING iv_name TYPE string.
164
+ METHODS process REDEFINITION.
165
+ ENDCLASS.
166
+
167
+ CLASS zcl_child IMPLEMENTATION.
168
+ METHOD constructor.
169
+ super->constructor( iv_name ).
170
+ ENDMETHOD.
171
+ METHOD process.
172
+ super->process( ).
173
+ " Child-specific logic
174
+ ENDMETHOD.
175
+ ENDCLASS.
176
+ ```
177
+
178
+ ## Abstract Classes
179
+
180
+ ```abap
181
+ CLASS zcl_base DEFINITION ABSTRACT PUBLIC.
182
+ PUBLIC SECTION.
183
+ METHODS concrete_method.
184
+ METHODS abstract_method ABSTRACT.
185
+ ENDCLASS.
186
+
187
+ CLASS zcl_concrete DEFINITION
188
+ INHERITING FROM zcl_base FINAL PUBLIC.
189
+ PUBLIC SECTION.
190
+ METHODS abstract_method REDEFINITION.
191
+ ENDCLASS.
192
+ ```
193
+
194
+ ## Type Checking and Casting
195
+
196
+ ```abap
197
+ " Instance check
198
+ IF zo_ref IS INSTANCE OF zif_processable.
199
+ DATA(zo_intf) = CAST zif_processable( zo_ref ).
200
+ ENDIF.
201
+
202
+ " Safe casting
203
+ TRY.
204
+ DATA(zo_specific) = CAST zcl_specific( zo_general ).
205
+ CATCH cx_sy_move_cast_error.
206
+ ENDTRY.
207
+
208
+ " RTTI
209
+ DATA(zo_descr) = CAST cl_abap_classdescr(
210
+ cl_abap_typedescr=>describe_by_object_ref( zo_ref ) ).
211
+ ```
212
+
213
+ ## Events
214
+
215
+ ```abap
216
+ " Publisher
217
+ CLASS zcl_publisher DEFINITION PUBLIC.
218
+ PUBLIC SECTION.
219
+ EVENTS data_changed
220
+ EXPORTING VALUE(ev_old) TYPE string
221
+ VALUE(ev_new) TYPE string.
222
+ METHODS set_data IMPORTING iv_data TYPE string.
223
+ PRIVATE SECTION.
224
+ DATA mv_data TYPE string.
225
+ ENDCLASS.
226
+
227
+ CLASS zcl_publisher IMPLEMENTATION.
228
+ METHOD set_data.
229
+ DATA(lv_old) = mv_data.
230
+ mv_data = iv_data.
231
+ RAISE EVENT data_changed
232
+ EXPORTING ev_old = lv_old ev_new = iv_data.
233
+ ENDMETHOD.
234
+ ENDCLASS.
235
+
236
+ " Subscriber
237
+ CLASS zcl_subscriber DEFINITION PUBLIC.
238
+ PUBLIC SECTION.
239
+ METHODS on_changed FOR EVENT data_changed OF zcl_publisher
240
+ IMPORTING ev_old ev_new sender.
241
+ ENDCLASS.
242
+
243
+ " Registration
244
+ SET HANDLER zo_subscriber->on_changed FOR zo_publisher.
245
+ ```
246
+
247
+ ## Exception Classes
248
+
249
+ ```abap
250
+ CLASS zcx_order_error DEFINITION
251
+ INHERITING FROM cx_static_check
252
+ PUBLIC FINAL CREATE PUBLIC.
253
+ PUBLIC SECTION.
254
+ INTERFACES if_t100_message.
255
+ METHODS constructor
256
+ IMPORTING textid LIKE if_t100_message=>t100key OPTIONAL
257
+ previous LIKE previous OPTIONAL.
258
+ ENDCLASS.
259
+ ```
260
+
261
+ ## Friendship
262
+
263
+ ```abap
264
+ CLASS zcl_private DEFINITION FRIENDS zcl_tester.
265
+ PRIVATE SECTION.
266
+ DATA mv_secret TYPE string.
267
+ ENDCLASS.
268
+ " zcl_tester can access mv_secret
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Rules
274
+
275
+ - Prefer FINAL unless inheritance is explicitly needed
276
+ - Program to interfaces, not implementations
277
+ - Use CREATE PRIVATE + factory method for controlled instantiation
278
+ - Use ALIASES to simplify interface method access
279
+ - Keep classes focused — Single Responsibility Principle
280
+ - Prefer composition over inheritance
281
+ - Use cx_static_check for expected errors, cx_no_check for programming errors
282
+ - RETURNING parameters enable functional chaining — prefer over EXPORTING when single output
283
+ - Use ABSTRACT for template method pattern
284
+
285
+ ## Anti-Patterns
286
+
287
+ | Anti-Pattern | Correct Approach |
288
+ |---|---|
289
+ | `CREATE OBJECT oref TYPE zcl_class` | `NEW zcl_class( )` |
290
+ | Giant class with 50+ methods | Split into focused classes + interface |
291
+ | Public attributes modified externally | Use getter/setter methods |
292
+ | Deep inheritance hierarchy (3+ levels) | Composition + interfaces |
293
+ | Catching `cx_root` everywhere | Catch specific exception classes |
294
+ | Empty CATCH blocks | At minimum log the error |
295
+ | PROTECTED SECTION with many attributes | Keep PROTECTED minimal, prefer PRIVATE |
296
+ | Static methods accessing instance data | Use instance methods or pass data as parameters |
297
+ | Missing FINAL on leaf classes | Always add FINAL unless subclassing is intended |
298
+ | Using FRIENDS for production code | FRIENDS only for unit test access |
@@ -0,0 +1,216 @@
1
+ # ABAP Performance — SELECT, internal tables, buffering, code optimization
2
+
3
+ ## SELECT Optimization
4
+
5
+ ```abap
6
+ " ONLY needed fields (never SELECT *)
7
+ SELECT order_id, customer_id, status
8
+ FROM ztab_order
9
+ INTO TABLE @DATA(lt_orders).
10
+
11
+ " Use INTO TABLE (not ENDSELECT loop)
12
+ " BAD:
13
+ SELECT * FROM ztab_order INTO @DATA(ls_order).
14
+ " process row by row — very slow
15
+ ENDSELECT.
16
+
17
+ " GOOD:
18
+ SELECT * FROM ztab_order INTO TABLE @DATA(lt_orders).
19
+ LOOP AT lt_orders INTO DATA(ls_order).
20
+ " process in memory — much faster
21
+ ENDLOOP.
22
+
23
+ " Use JOIN instead of nested SELECT
24
+ " BAD:
25
+ SELECT * FROM ztab_order INTO TABLE @DATA(lt_orders).
26
+ LOOP AT lt_orders INTO DATA(ls_ord).
27
+ SELECT SINGLE name FROM ztab_customer
28
+ WHERE customer_id = @ls_ord-customer_id INTO @DATA(lv_name).
29
+ ENDLOOP.
30
+
31
+ " GOOD:
32
+ SELECT o~order_id, o~customer_id, c~name
33
+ FROM ztab_order AS o
34
+ INNER JOIN ztab_customer AS c ON o~customer_id = c~customer_id
35
+ INTO TABLE @DATA(lt_joined).
36
+
37
+ " Use FOR ALL ENTRIES (with empty check)
38
+ IF lt_keys IS NOT INITIAL.
39
+ SELECT * FROM ztab_detail
40
+ FOR ALL ENTRIES IN @lt_keys
41
+ WHERE order_id = @lt_keys-order_id
42
+ INTO TABLE @DATA(lt_details).
43
+ ENDIF.
44
+
45
+ " Use aggregation in SQL
46
+ " BAD:
47
+ SELECT * FROM ztab_order INTO TABLE @DATA(lt_all).
48
+ DATA(lv_sum) = REDUCE decfloat34( INIT s = 0
49
+ FOR wa IN lt_all NEXT s = s + wa-amount ).
50
+
51
+ " GOOD:
52
+ SELECT SINGLE SUM( amount ) FROM ztab_order INTO @DATA(lv_sum).
53
+
54
+ " PACKAGE SIZE for millions of rows
55
+ SELECT * FROM ztab_big INTO TABLE @DATA(lt_chunk) PACKAGE SIZE 10000.
56
+ " process chunk
57
+ CLEAR lt_chunk.
58
+ ENDSELECT.
59
+
60
+ " Existence check (not SELECT COUNT)
61
+ " BAD:
62
+ SELECT COUNT(*) FROM ztab_order WHERE order_id = @lv_id INTO @DATA(lv_cnt).
63
+ IF lv_cnt > 0.
64
+
65
+ " GOOD:
66
+ SELECT SINGLE @abap_true FROM ztab_order
67
+ WHERE order_id = @lv_id INTO @DATA(lv_exists).
68
+ IF lv_exists = abap_true.
69
+ ```
70
+
71
+ ## Internal Table Optimization
72
+
73
+ ```abap
74
+ " Use correct table type for access pattern
75
+ " Sequential processing → STANDARD TABLE
76
+ " Frequent key lookup → SORTED TABLE (binary search O(log n))
77
+ " Hash lookup → HASHED TABLE (O(1))
78
+
79
+ " BAD: READ TABLE on STANDARD TABLE (linear scan O(n))
80
+ DATA lt_std TYPE STANDARD TABLE OF zs_item WITH EMPTY KEY.
81
+ READ TABLE lt_std WITH KEY order_id = lv_id INTO DATA(ls_found).
82
+
83
+ " GOOD: SORTED TABLE (binary search)
84
+ DATA lt_sorted TYPE SORTED TABLE OF zs_item WITH UNIQUE KEY order_id.
85
+ DATA(ls_found2) = lt_sorted[ order_id = lv_id ].
86
+
87
+ " GOOD: HASHED TABLE for large datasets
88
+ DATA lt_hashed TYPE HASHED TABLE OF zs_item WITH UNIQUE KEY order_id.
89
+ DATA(ls_found3) = lt_hashed[ order_id = lv_id ].
90
+
91
+ " Use FIELD-SYMBOL in LOOP (no copy)
92
+ " BAD:
93
+ LOOP AT lt_items INTO DATA(ls_item).
94
+ ls_item-amount = ls_item-amount * 1.1.
95
+ MODIFY lt_items FROM ls_item.
96
+ ENDLOOP.
97
+
98
+ " GOOD:
99
+ LOOP AT lt_items ASSIGNING FIELD-SYMBOL(<item>).
100
+ <item>-amount = <item>-amount * 1.1.
101
+ ENDLOOP.
102
+
103
+ " Use secondary keys for multiple access patterns
104
+ DATA lt_multi TYPE TABLE OF zs_item
105
+ WITH EMPTY KEY
106
+ WITH NON-UNIQUE SORTED KEY by_customer COMPONENTS customer_id
107
+ WITH UNIQUE HASHED KEY by_id COMPONENTS order_id.
108
+
109
+ DATA(ls_by_id) = lt_multi[ KEY by_id order_id = '1000' ].
110
+ LOOP AT lt_multi USING KEY by_customer ASSIGNING FIELD-SYMBOL(<fs>)
111
+ WHERE customer_id = 'CUST100'.
112
+ ENDLOOP.
113
+
114
+ " Use FILTER (requires sorted/hashed key)
115
+ DATA(lt_active) = FILTER #( lt_multi USING KEY by_customer
116
+ WHERE customer_id = 'CUST100' ).
117
+
118
+ " DELETE ADJACENT DUPLICATES — SORT first
119
+ SORT lt_items BY order_id.
120
+ DELETE ADJACENT DUPLICATES FROM lt_items COMPARING order_id.
121
+ ```
122
+
123
+ ## Avoid Nested Loops
124
+
125
+ ```abap
126
+ " BAD: O(n*m) — nested LOOP
127
+ LOOP AT lt_orders INTO DATA(ls_order).
128
+ LOOP AT lt_items INTO DATA(ls_item) WHERE order_id = ls_order-order_id.
129
+ " process
130
+ ENDLOOP.
131
+ ENDLOOP.
132
+
133
+ " GOOD: O(n+m) — GROUP BY
134
+ LOOP AT lt_items INTO DATA(ls_rep)
135
+ GROUP BY ( order_id = ls_rep-order_id )
136
+ ASSIGNING FIELD-SYMBOL(<group>).
137
+ LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<member>).
138
+ " process
139
+ ENDLOOP.
140
+ ENDLOOP.
141
+
142
+ " GOOD: O(n*log m) — SORTED TABLE inner
143
+ DATA lt_items_sorted TYPE SORTED TABLE OF zs_item WITH NON-UNIQUE KEY order_id.
144
+ lt_items_sorted = lt_items.
145
+ LOOP AT lt_orders INTO ls_order.
146
+ LOOP AT lt_items_sorted INTO ls_item
147
+ WHERE order_id = ls_order-order_id.
148
+ " binary search on first access
149
+ ENDLOOP.
150
+ ENDLOOP.
151
+ ```
152
+
153
+ ## String Optimization
154
+
155
+ ```abap
156
+ " Use string templates (not CONCATENATE for multiple joins)
157
+ DATA(lv_msg) = |Order { lv_id } for { lv_customer }|.
158
+
159
+ " For large string building, use string_table + CONCATENATE LINES OF
160
+ DATA lt_lines TYPE string_table.
161
+ LOOP AT lt_data INTO DATA(ls_data).
162
+ APPEND |{ ls_data-field1 },{ ls_data-field2 }| TO lt_lines.
163
+ ENDLOOP.
164
+ CONCATENATE LINES OF lt_lines INTO DATA(lv_csv) SEPARATED BY cl_abap_char_utilities=>newline.
165
+ ```
166
+
167
+ ## Buffering Hints
168
+
169
+ ```abap
170
+ " CDS View — enable buffering
171
+ @AbapCatalog.buffering.status: #ACTIVE
172
+ @AbapCatalog.buffering.type: #FULL " Entire table cached
173
+ @AbapCatalog.buffering.type: #SINGLE " By primary key
174
+ @AbapCatalog.buffering.type: #GENERIC " By n key fields
175
+ @AbapCatalog.buffering.numberOfKeyFields: 2 " For GENERIC
176
+
177
+ " ABAP — bypass buffer when needed
178
+ SELECT SINGLE * FROM ztab BYPASSING BUFFER WHERE id = @lv_id INTO @DATA(ls).
179
+ ```
180
+
181
+ ## Parallel Processing
182
+
183
+ ```abap
184
+ " AMDP / CDS for DB-level parallel processing
185
+ " Background jobs for long-running tasks
186
+
187
+ " NEW with async RFC (only when truly needed)
188
+ CALL FUNCTION 'ZFUNC' STARTING NEW TASK 'TASK1'
189
+ PERFORMING callback ON END OF TASK
190
+ EXPORTING iv_param = lv_value.
191
+ ```
192
+
193
+ ## Rules
194
+ - SELECT only needed fields — `SELECT *` reads unnecessary data
195
+ - INTO TABLE, not ENDSELECT — avoid row-by-row processing
196
+ - JOIN instead of SELECT in LOOP — single DB roundtrip
197
+ - FOR ALL ENTRIES: always check IS NOT INITIAL before
198
+ - Aggregation in SQL, not in ABAP — let the DB do the math
199
+ - SORTED/HASHED tables for frequent key lookups
200
+ - FIELD-SYMBOL in LOOP for modification — no copy overhead
201
+ - PACKAGE SIZE for millions of rows — avoid memory overflow
202
+ - Existence check: `SELECT SINGLE @abap_true` instead of `COUNT(*)`
203
+
204
+ ## Anti-Patterns
205
+ | Anti-Pattern | Correct |
206
+ |---|---|
207
+ | `SELECT *` in production | Select only needed fields |
208
+ | `SELECT ... ENDSELECT` (row by row) | `SELECT ... INTO TABLE` |
209
+ | SELECT inside LOOP | JOIN or FOR ALL ENTRIES |
210
+ | FOR ALL ENTRIES without empty check | `IF itab IS NOT INITIAL` |
211
+ | `LOOP INTO DATA(wa)` for modification | `LOOP ASSIGNING FIELD-SYMBOL(<fs>)` |
212
+ | Nested LOOP for lookup O(n*m) | HASHED/SORTED table or GROUP BY |
213
+ | `SELECT COUNT(*)` for existence | `SELECT SINGLE @abap_true` |
214
+ | Aggregation in ABAP LOOP | `SELECT SUM/AVG/COUNT` in SQL |
215
+ | STANDARD TABLE + READ TABLE (linear) | SORTED TABLE (binary) or HASHED (hash) |
216
+ | `CONCATENATE` in LOOP for large strings | Collect in string_table, join once |
@@ -0,0 +1,206 @@
1
+ # RAP Abstract Entities — action parameters and function returns
2
+
3
+ ## What They Are
4
+
5
+ Abstract entities define structured types without DB persistence. Used for:
6
+ - Action input parameters
7
+ - Action/function return types
8
+ - Complex result structures
9
+
10
+ ## Defining Abstract Entity
11
+
12
+ ```abap
13
+ @EndUserText.label: 'Action Parameter: Reject Reason'
14
+ define abstract entity ZA_RejectParams
15
+ {
16
+ reason : abap.char(256);
17
+ note : abap.string;
18
+ reject_date : abap.dats;
19
+ }
20
+ ```
21
+
22
+ ```abap
23
+ @EndUserText.label: 'Action Result: Confirmation'
24
+ define abstract entity ZA_ConfirmResult
25
+ {
26
+ order_id : abap.numc(10);
27
+ status : abap.char(1);
28
+ message : abap.char(256);
29
+ changed_at : abp_lastchange_tstmpl;
30
+ }
31
+ ```
32
+
33
+ ## Using in BDEF — Action with Parameters
34
+
35
+ ```abap
36
+ define behavior for ZI_Order alias Order
37
+ {
38
+ " Action with input parameter
39
+ action rejectOrder parameter ZA_RejectParams result [1] $self;
40
+
41
+ " Action with result type (not $self)
42
+ action confirmOrder result [1] ZA_ConfirmResult;
43
+
44
+ " Action with parameter AND custom result
45
+ action processOrder parameter ZA_ProcessParams result [1] ZA_ProcessResult;
46
+
47
+ " Action without parameter, with result
48
+ action acceptOrder result [1] $self;
49
+
50
+ " Action without parameter, without result
51
+ action cancelOrder;
52
+
53
+ " Static action with parameter
54
+ static action bulkProcess parameter ZA_BulkParams result [0..*] ZA_BulkResult;
55
+ }
56
+ ```
57
+
58
+ ## Handler — Action with Parameter
59
+
60
+ ```abap
61
+ METHOD rejectOrder.
62
+ " req.data contains the parameter fields
63
+ " keys contains the entity keys
64
+
65
+ MODIFY ENTITIES OF ZI_Order IN LOCAL MODE
66
+ ENTITY Order
67
+ UPDATE FIELDS ( Status RejectReason RejectDate )
68
+ WITH VALUE #( FOR key IN keys
69
+ ( %tky = key-%tky
70
+ Status = 'X'
71
+ RejectReason = key-%param-reason
72
+ RejectDate = key-%param-reject_date ) )
73
+ FAILED failed
74
+ REPORTED reported.
75
+
76
+ " Return updated instance
77
+ READ ENTITIES OF ZI_Order IN LOCAL MODE
78
+ ENTITY Order ALL FIELDS
79
+ WITH CORRESPONDING #( keys )
80
+ RESULT DATA(orders).
81
+
82
+ result = VALUE #( FOR order IN orders
83
+ ( %tky = order-%tky %param = order ) ).
84
+ ENDMETHOD.
85
+ ```
86
+
87
+ ## Handler — Action with Custom Result
88
+
89
+ ```abap
90
+ METHOD confirmOrder.
91
+ MODIFY ENTITIES OF ZI_Order IN LOCAL MODE
92
+ ENTITY Order
93
+ UPDATE FIELDS ( Status )
94
+ WITH VALUE #( FOR key IN keys
95
+ ( %tky = key-%tky Status = 'A' ) )
96
+ FAILED failed
97
+ REPORTED reported.
98
+
99
+ READ ENTITIES OF ZI_Order IN LOCAL MODE
100
+ ENTITY Order FIELDS ( OrderID Status LastChangedAt )
101
+ WITH CORRESPONDING #( keys )
102
+ RESULT DATA(orders).
103
+
104
+ result = VALUE #( FOR order IN orders
105
+ ( %tky = order-%tky
106
+ %param = VALUE ZA_ConfirmResult(
107
+ order_id = order-OrderID
108
+ status = order-Status
109
+ message = |Order { order-OrderID } confirmed|
110
+ changed_at = order-LastChangedAt ) ) ).
111
+ ENDMETHOD.
112
+ ```
113
+
114
+ ## Handler — Static Action with Parameter
115
+
116
+ ```abap
117
+ METHOD bulkProcess.
118
+ " Static action — no entity keys, only parameter data
119
+ DATA(lv_params) = keys[ 1 ]-%param.
120
+
121
+ " Process based on parameter
122
+ SELECT * FROM ztab_order
123
+ WHERE status = @lv_params-filter_status
124
+ INTO TABLE @DATA(lt_orders).
125
+
126
+ " ... process orders ...
127
+
128
+ result = VALUE #( FOR order IN lt_orders
129
+ ( %param = VALUE ZA_BulkResult(
130
+ order_id = order-order_id
131
+ processed = abap_true ) ) ).
132
+ ENDMETHOD.
133
+ ```
134
+
135
+ ## Abstract Entity with Associations (for complex results)
136
+
137
+ ```abap
138
+ @EndUserText.label: 'Order Summary Result'
139
+ define abstract entity ZA_OrderSummary
140
+ {
141
+ order_id : abap.numc(10);
142
+ customer_id : kunnr;
143
+ total_amount : abap.curr(17,2);
144
+ currency_code : abap.cuky(5);
145
+ item_count : abap.int4;
146
+ status_text : abap.char(20);
147
+ }
148
+ ```
149
+
150
+ ## Projection BDEF — Exposing Actions with Parameters
151
+
152
+ ```abap
153
+ projection;
154
+ strict ( 2 );
155
+ use draft;
156
+
157
+ define behavior for ZC_Order alias Order
158
+ use etag
159
+ {
160
+ use create; use update; use delete;
161
+ use action Edit; use action Activate; use action Discard;
162
+ use action Resume; use action Prepare;
163
+
164
+ use action rejectOrder; " Parameter inherited from interface
165
+ use action confirmOrder; " Result type inherited from interface
166
+ use action acceptOrder;
167
+ use action bulkProcess;
168
+ }
169
+ ```
170
+
171
+ ## Fiori UI — Action Dialog for Parameters
172
+
173
+ When an action has a parameter, Fiori Elements automatically generates a dialog with input fields for the abstract entity's fields.
174
+
175
+ ```abap
176
+ " Metadata Extension — customize action parameter dialog
177
+ @Metadata.layer: #CORE
178
+ annotate entity ZA_RejectParams with
179
+ {
180
+ @UI.defaultValue: 'Rejected by user'
181
+ reason;
182
+
183
+ @UI.hidden: true
184
+ reject_date;
185
+ }
186
+ ```
187
+
188
+ ## Rules
189
+ - Abstract entities: `define abstract entity` — no DB table, no persistence
190
+ - Use for action parameters when more than 1-2 simple fields needed
191
+ - `$self` returns the entity itself; custom abstract entity returns different structure
192
+ - `result [1]` = exactly one result; `result [0..*]` = multiple results
193
+ - `%param` in handler: `key-%param-fieldname` for parameter fields
194
+ - Static actions: no entity key, parameter accessed via `keys[ 1 ]-%param`
195
+ - Abstract entities can use data elements for labels and search helps
196
+ - Fiori auto-generates dialog for action parameters based on abstract entity fields
197
+
198
+ ## Anti-Patterns
199
+ | Anti-Pattern | Correct |
200
+ |---|---|
201
+ | Using STRING for action params that need structure | Define abstract entity |
202
+ | `result [1] $self` when return differs from entity | Use custom abstract entity as result |
203
+ | Accessing `keys-%param` without checking keys is not empty | Guard with `IF keys IS NOT INITIAL` |
204
+ | Abstract entity with too many fields (>10) | Keep focused — split into multiple if complex |
205
+ | Missing labels on abstract entity fields | Use data elements or `@EndUserText.label` |
206
+ | Forgetting to `use action` in projection BDEF | Action not available in Fiori |