Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

more ADBC #921

Merged
merged 22 commits into from
Jan 29, 2025
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ jobs:
integration:
needs: unit
runs-on: ubuntu-latest
timeout-minutes: 5
timeout-minutes: 10
env:
HTTP_BIN_HOST: http://localhost:8080
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: docker run -d -p8080:80 kennethreitz/httpbin
- run: npm run docker:start
- run: npm install
- run: npm run integration
performance:
Expand Down
13 changes: 11 additions & 2 deletions abaplint.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
"inline_data_old_versions": false,
"intf_referencing_clas": false,
"keep_single_parameter_on_one_line": true,
"line_break_multiple_parameters": false,
"line_break_multiple_parameters": true,
"line_break_style": false,
"msag_consistency": true,
"nesting": true,
Expand Down Expand Up @@ -182,7 +182,16 @@
"check_ddic": true,
"implement_methods": true,
"indentation": true,
"keyword_case": true,
"keyword_case": {
"style": "upper",
"ignoreExceptions": false,
"ignoreLowerClassImplmentationStatement": false,
"ignoreGlobalClassDefinition": false,
"ignoreGlobalInterface": false,
"ignoreFunctionModuleName": false,
"ignoreGlobalClassBoundaries": false,
"ignoreKeywords": []
},
"when_others_last": true,
"newline_between_methods": true,
"avoid_use": {
Expand Down
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
"flame": "0x -o -- node --expose-gc test/performance.mjs",
"performance": "rm -rf output && abap_transpile ./abap_transpile_test.json && node --expose-gc test/performance.mjs",
"integration": "rm -rf output && abap_transpile ./abap_transpile_test.json && node --expose-gc output/index.mjs",
"postgres:init": "cat test/adbc/init.sql | docker exec -i postgresql psql -U postgres -d postgres",
"docker:start": "docker compose -p open-abap -f test/stack.yml up -d --wait && npm run postgres:init",
"test": "npm run lint && npm run unit"
},
"license": "MIT",
"dependencies": {
"@abaplint/cli": "^2.113.91",
"@abaplint/database-sqlite": "^2.10.20",
"@abaplint/runtime": "^2.10.23",
"@abaplint/transpiler-cli": "^2.10.23",
"@abaplint/cli": "^2.113.99",
"@abaplint/database-pg": "^2.10.24",
"@abaplint/database-sqlite": "^2.10.24",
"@abaplint/runtime": "^2.10.24",
"@abaplint/transpiler-cli": "^2.10.24",
"0x": "^5.8.0"
}
}
4 changes: 3 additions & 1 deletion src/abap/math/cl_abap_random.clas.testclasses.abap
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ CLASS ltcl_test IMPLEMENTATION.
DATA lv_int TYPE i.
lo_random = cl_abap_random=>create( ).
DO 10 TIMES.
lv_int = lo_random->intinrange( low = 10 high = 20 ).
lv_int = lo_random->intinrange(
low = 10
high = 20 ).
cl_abap_unit_assert=>assert_number_between(
lower = 10
upper = 20
Expand Down
51 changes: 51 additions & 0 deletions src/adbc/cl_sql_connection.clas.abap
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
CLASS cl_sql_connection DEFINITION PUBLIC.
PUBLIC SECTION.
CLASS-METHODS get_connection
IMPORTING
con_name TYPE clike
sharable TYPE abap_bool DEFAULT abap_false
RETURNING
VALUE(connection) TYPE REF TO cl_sql_connection.

" added in 7.53
CLASS-METHODS get_abap_connection
IMPORTING
con_name TYPE clike
RETURNING
VALUE(connection) TYPE REF TO cl_sql_connection.

METHODS create_statement
RETURNING
VALUE(statement) TYPE REF TO cl_sql_statement.

METHODS get_con_name
RETURNING
VALUE(con_name) TYPE string.

PRIVATE SECTION.
DATA mv_con_name TYPE string.
ENDCLASS.

CLASS cl_sql_connection IMPLEMENTATION.
METHOD get_con_name.
con_name = mv_con_name.
ENDMETHOD.

METHOD create_statement.
CREATE OBJECT statement EXPORTING con_ref = me.
ENDMETHOD.

METHOD get_connection.
" only supported for now,
ASSERT sharable = abap_true.
CREATE OBJECT connection.
connection->mv_con_name = con_name.
ENDMETHOD.

METHOD get_abap_connection.
connection = get_connection(
con_name = con_name
sharable = abap_true ).
ENDMETHOD.

ENDCLASS.
40 changes: 24 additions & 16 deletions src/adbc/cl_sql_statement.clas.abap
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
CLASS cl_sql_statement DEFINITION PUBLIC.
PUBLIC SECTION.
METHODS constructor
IMPORTING con_ref TYPE REF TO object OPTIONAL.
IMPORTING
con_ref TYPE REF TO cl_sql_connection OPTIONAL.

METHODS execute_update
IMPORTING
Expand All @@ -22,13 +23,21 @@ CLASS cl_sql_statement DEFINITION PUBLIC.
statement TYPE string
RAISING
cx_sql_exception.

PRIVATE SECTION.
DATA mv_connection TYPE string.
ENDCLASS.

CLASS cl_sql_statement IMPLEMENTATION.

METHOD constructor.
* todo,
ASSERT con_ref IS INITIAL.
IF con_ref IS INITIAL.
mv_connection = 'DEFAULT'.
ELSE.
mv_connection = con_ref->get_con_name( ).
ENDIF.

ASSERT mv_connection IS NOT INITIAL.
ENDMETHOD.

METHOD execute_ddl.
Expand All @@ -41,15 +50,15 @@ CLASS cl_sql_statement IMPLEMENTATION.

ASSERT statement IS NOT INITIAL.

WRITE '@KERNEL if (abap.context.databaseConnections["DEFAULT"] === undefined) {'.
WRITE '@KERNEL if (abap.context.databaseConnections[this.mv_connection.get()] === undefined) {'.
lv_sql_message = 'not connected to db'.
WRITE '@KERNEL }'.
IF lv_sql_message IS NOT INITIAL.
RAISE EXCEPTION TYPE cx_sql_exception.
ENDIF.

WRITE '@KERNEL try {'.
WRITE '@KERNEL await abap.context.databaseConnections["DEFAULT"].execute(statement.get());'.
WRITE '@KERNEL await abap.context.databaseConnections[this.mv_connection.get()].execute(statement.get());'.
WRITE '@KERNEL } catch(e) {'.
WRITE '@KERNEL lv_sql_message.set(e + "");'.
WRITE '@KERNEL }'.
Expand All @@ -60,29 +69,28 @@ CLASS cl_sql_statement IMPLEMENTATION.
ENDMETHOD.

METHOD execute_query.
DATA lx_osql TYPE REF TO cx_sy_dynamic_osql_semantics.
DATA lv_sql_message TYPE string.

ASSERT statement IS NOT INITIAL.
ASSERT mv_connection IS NOT INITIAL.

WRITE '@KERNEL if (abap.context.databaseConnections["DEFAULT"] === undefined) {'.
WRITE '@KERNEL if (abap.context.databaseConnections[this.mv_connection.get()] === undefined) {'.
lv_sql_message = 'not connected to db'.
WRITE '@KERNEL }'.
IF lv_sql_message IS NOT INITIAL.
RAISE EXCEPTION TYPE cx_sql_exception.
RAISE EXCEPTION TYPE cx_sql_exception EXPORTING sql_message = lv_sql_message.
ENDIF.

CREATE OBJECT result_set.

WRITE '@KERNEL try {'.
WRITE '@KERNEL const res = await abap.context.databaseConnections["DEFAULT"].select({select: statement.get()});'.
TRY.
WRITE '@KERNEL const res = await abap.context.databaseConnections[this.mv_connection.get()].select({select: statement.get()});'.
* WRITE '@KERNEL console.dir(res.rows);'.
WRITE '@KERNEL result_set.get().mv_magic = res.rows;'.
WRITE '@KERNEL } catch(e) {'.
WRITE '@KERNEL lv_sql_message.set(e + "");'.
WRITE '@KERNEL }'.
IF lv_sql_message IS NOT INITIAL.
RAISE EXCEPTION TYPE cx_sql_exception.
ENDIF.
WRITE '@KERNEL result_set.get().mv_magic = res.rows;'.
CATCH cx_sy_dynamic_osql_semantics INTO lx_osql.
RAISE EXCEPTION TYPE cx_sql_exception EXPORTING sql_message = lx_osql->sqlmsg.
ENDTRY.

ENDMETHOD.

Expand Down
14 changes: 14 additions & 0 deletions src/adbc/cx_sql_exception.clas.abap
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
CLASS cx_sql_exception DEFINITION PUBLIC INHERITING FROM cx_static_check.
PUBLIC SECTION.
DATA sql_message TYPE string.

METHODS constructor
IMPORTING
textid LIKE textid OPTIONAL
sql_message TYPE string OPTIONAL
previous TYPE REF TO cx_root OPTIONAL.
ENDCLASS.

CLASS cx_sql_exception IMPLEMENTATION.
METHOD constructor.
super->constructor(
textid = textid
previous = previous ).

me->sql_message = sql_message.
ENDMETHOD.

ENDCLASS.
20 changes: 14 additions & 6 deletions src/date_time/cl_abap_datfm.clas.testclasses.abap
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@ CLASS ltcl_test_datfm IMPLEMENTATION.
ex_datint = date_internal_actual
ex_datfmused = format_used_actual ).

cl_abap_unit_assert=>assert_equals( exp = christmas act = date_internal_actual ).
cl_abap_unit_assert=>assert_equals( exp = gregorian_dot_seperated act = format_used_actual ).
cl_abap_unit_assert=>assert_equals(
exp = christmas
act = date_internal_actual ).
cl_abap_unit_assert=>assert_equals(
exp = gregorian_dot_seperated
act = format_used_actual ).
ENDMETHOD.

METHOD acc_conv_ext_to_int_infinity.
Expand All @@ -55,8 +59,10 @@ CLASS ltcl_test_datfm IMPLEMENTATION.
ex_datint = date_internal_actual
ex_datfmused = format_used_actual ).

cl_abap_unit_assert=>assert_equals( exp = infinity act = date_internal_actual ).
cl_abap_unit_assert=>assert_equals( exp = gregorian_dot_seperated act = format_used_actual ).
cl_abap_unit_assert=>assert_equals( exp = infinity
act = date_internal_actual ).
cl_abap_unit_assert=>assert_equals( exp = gregorian_dot_seperated
act = format_used_actual ).
ENDMETHOD.

METHOD acc_conv_ext_to_int_initial.
Expand All @@ -73,8 +79,10 @@ CLASS ltcl_test_datfm IMPLEMENTATION.
ex_datint = date_internal_actual
ex_datfmused = format_used_actual ).

cl_abap_unit_assert=>assert_equals( exp = initial act = date_internal_actual ).
cl_abap_unit_assert=>assert_equals( exp = gregorian_dot_seperated act = format_used_actual ).
cl_abap_unit_assert=>assert_equals( exp = initial
act = date_internal_actual ).
cl_abap_unit_assert=>assert_equals( exp = gregorian_dot_seperated
act = format_used_actual ).
ENDMETHOD.


Expand Down
3 changes: 2 additions & 1 deletion src/http/cl_http_utility.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ CLASS cl_http_utility IMPLEMENTATION.
str = ls_field-name && '=' && ls_field-value.
APPEND str TO tab.
ENDLOOP.
string = concat_lines_of( table = tab sep = '&' ).
string = concat_lines_of( table = tab
sep = '&' ).
ENDMETHOD.

METHOD encode_x_base64.
Expand Down
6 changes: 4 additions & 2 deletions src/ixml/cl_ixml.clas.locals_imp.abap
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@ CLASS lcl_node IMPLEMENTATION.
li_children = if_ixml_node~get_children( ).

IF mv_name <> '#text' AND ostream->get_pretty_print( ) = abap_true.
ostream->write_string( repeat( val = | | occ = ostream->get_indent( ) ) ).
ostream->write_string( repeat( val = | |
occ = ostream->get_indent( ) ) ).
ENDIF.

IF mv_name <> '#text'.
Expand Down Expand Up @@ -439,7 +440,8 @@ CLASS lcl_node IMPLEMENTATION.
ostream->write_string( lcl_escape=>escape_value( mv_value ) ).
IF mv_name <> '#text'.
IF ostream->get_pretty_print( ) = abap_true AND has_direct_text( ) = abap_false.
ostream->write_string( repeat( val = | | occ = ostream->get_indent( ) ) ).
ostream->write_string( repeat( val = | |
occ = ostream->get_indent( ) ) ).
ENDIF.
ostream->write_string( '</' && lv_ns && mv_name && '>' ).
ENDIF.
Expand Down
24 changes: 16 additions & 8 deletions src/ixml/cl_ixml.clas.testclasses.abap
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,8 @@ CLASS ltcl_xml IMPLEMENTATION.
lv_xml = |<?xml version="1.0" encoding="utf-16"?><abapGit vers="abc" foo="2"></abapGit>|.
li_doc = parse( lv_xml ).

li_node ?= li_doc->find_from_name_ns( depth = 0 name = 'abapGit' ).
li_node ?= li_doc->find_from_name_ns( depth = 0
name = 'abapGit' ).
li_version = li_node->get_attributes( )->get_named_item_ns( 'vers' ).

cl_abap_unit_assert=>assert_not_initial( li_version ).
Expand All @@ -503,7 +504,8 @@ CLASS ltcl_xml IMPLEMENTATION.
lv_xml = |<?xml version="1.0" encoding="utf-16"?><abapGit version="v1.0.0" serializer="LCL_OBJECT_DTEL"></abapGit>|.
li_doc = parse( lv_xml ).

li_element ?= li_doc->find_from_name_ns( depth = 0 name = 'abapGit' ).
li_element ?= li_doc->find_from_name_ns( depth = 0
name = 'abapGit' ).
cl_abap_unit_assert=>assert_not_initial( li_element ).

cl_abap_unit_assert=>assert_equals(
Expand All @@ -523,7 +525,8 @@ CLASS ltcl_xml IMPLEMENTATION.
lv_xml = |<?xml version="1.0" encoding="utf-16"?><abapGit></abapGit>|.
li_doc = parse( lv_xml ).

li_element ?= li_doc->find_from_name_ns( depth = 0 name = 'abapGit' ).
li_element ?= li_doc->find_from_name_ns( depth = 0
name = 'abapGit' ).
cl_abap_unit_assert=>assert_not_initial( li_element ).

* not found, should return blank
Expand All @@ -544,7 +547,8 @@ CLASS ltcl_xml IMPLEMENTATION.
lv_xml = |<?xml version="1.0" encoding="utf-16"?><DATA href="#o1"/>|.
li_doc = parse( lv_xml ).

li_element ?= li_doc->find_from_name_ns( depth = 0 name = 'DATA' ).
li_element ?= li_doc->find_from_name_ns( depth = 0
name = 'DATA' ).
cl_abap_unit_assert=>assert_not_initial( li_element ).

* not found, should return blank
Expand All @@ -564,10 +568,12 @@ CLASS ltcl_xml IMPLEMENTATION.
lv_xml = |<?xml version="1.0" encoding="utf-16"?><moo>&amp;&lt;&gt;&quot;&apos;</moo>|.
li_doc = parse( lv_xml ).

li_element ?= li_doc->find_from_name_ns( depth = 0 name = 'moo' ).
li_element ?= li_doc->find_from_name_ns( depth = 0
name = 'moo' ).
cl_abap_unit_assert=>assert_not_initial( li_element ).

li_element ?= mi_document->find_from_name_ns( depth = 0 name = 'moo' ).
li_element ?= mi_document->find_from_name_ns( depth = 0
name = 'moo' ).

cl_abap_unit_assert=>assert_equals(
act = li_element->get_value( )
Expand All @@ -585,10 +591,12 @@ CLASS ltcl_xml IMPLEMENTATION.
lv_xml = |<?xml version="1.0" encoding="utf-16"?><moo> A </moo>|.
li_doc = parse( lv_xml ).

li_element ?= li_doc->find_from_name_ns( depth = 0 name = 'moo' ).
li_element ?= li_doc->find_from_name_ns( depth = 0
name = 'moo' ).
cl_abap_unit_assert=>assert_not_initial( li_element ).

li_element ?= mi_document->find_from_name_ns( depth = 0 name = 'moo' ).
li_element ?= mi_document->find_from_name_ns( depth = 0
name = 'moo' ).

" todo
" cl_abap_unit_assert=>assert_equals(
Expand Down
Loading
Loading