diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 430acb8e..f7906c02 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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: diff --git a/abaplint.jsonc b/abaplint.jsonc index fc2898c3..314c4c82 100644 --- a/abaplint.jsonc +++ b/abaplint.jsonc @@ -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, @@ -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": { diff --git a/package.json b/package.json index 7813ce2f..a6b475ff 100644 --- a/package.json +++ b/package.json @@ -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" } } diff --git a/src/abap/math/cl_abap_random.clas.testclasses.abap b/src/abap/math/cl_abap_random.clas.testclasses.abap index d22c586a..23361ece 100644 --- a/src/abap/math/cl_abap_random.clas.testclasses.abap +++ b/src/abap/math/cl_abap_random.clas.testclasses.abap @@ -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 diff --git a/src/adbc/cl_sql_connection.clas.abap b/src/adbc/cl_sql_connection.clas.abap new file mode 100644 index 00000000..926a19cb --- /dev/null +++ b/src/adbc/cl_sql_connection.clas.abap @@ -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. \ No newline at end of file diff --git a/src/adbc/cl_sql_statement.clas.abap b/src/adbc/cl_sql_statement.clas.abap index 4aab0013..00e8743c 100644 --- a/src/adbc/cl_sql_statement.clas.abap +++ b/src/adbc/cl_sql_statement.clas.abap @@ -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 @@ -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. @@ -41,7 +50,7 @@ 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. @@ -49,7 +58,7 @@ CLASS cl_sql_statement IMPLEMENTATION. 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 }'. @@ -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. diff --git a/src/adbc/cx_sql_exception.clas.abap b/src/adbc/cx_sql_exception.clas.abap index 0fbb227a..9af72645 100644 --- a/src/adbc/cx_sql_exception.clas.abap +++ b/src/adbc/cx_sql_exception.clas.abap @@ -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. \ No newline at end of file diff --git a/src/date_time/cl_abap_datfm.clas.testclasses.abap b/src/date_time/cl_abap_datfm.clas.testclasses.abap index 45143295..051e53ad 100644 --- a/src/date_time/cl_abap_datfm.clas.testclasses.abap +++ b/src/date_time/cl_abap_datfm.clas.testclasses.abap @@ -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. @@ -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. @@ -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. diff --git a/src/http/cl_http_utility.clas.abap b/src/http/cl_http_utility.clas.abap index b8522625..66b579df 100644 --- a/src/http/cl_http_utility.clas.abap +++ b/src/http/cl_http_utility.clas.abap @@ -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. diff --git a/src/ixml/cl_ixml.clas.locals_imp.abap b/src/ixml/cl_ixml.clas.locals_imp.abap index a4499eb4..b367b92c 100644 --- a/src/ixml/cl_ixml.clas.locals_imp.abap +++ b/src/ixml/cl_ixml.clas.locals_imp.abap @@ -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'. @@ -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( '' ). ENDIF. diff --git a/src/ixml/cl_ixml.clas.testclasses.abap b/src/ixml/cl_ixml.clas.testclasses.abap index a2c75208..cce9fe42 100644 --- a/src/ixml/cl_ixml.clas.testclasses.abap +++ b/src/ixml/cl_ixml.clas.testclasses.abap @@ -481,7 +481,8 @@ CLASS ltcl_xml IMPLEMENTATION. lv_xml = ||. 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 ). @@ -503,7 +504,8 @@ CLASS ltcl_xml IMPLEMENTATION. lv_xml = ||. 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( @@ -523,7 +525,8 @@ CLASS ltcl_xml IMPLEMENTATION. lv_xml = ||. 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 @@ -544,7 +547,8 @@ CLASS ltcl_xml IMPLEMENTATION. lv_xml = ||. 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 @@ -564,10 +568,12 @@ CLASS ltcl_xml IMPLEMENTATION. lv_xml = |&<>"'|. 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( ) @@ -585,10 +591,12 @@ CLASS ltcl_xml IMPLEMENTATION. lv_xml = | A |. 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( diff --git a/src/json/#ui2#cl_json.clas.abap b/src/json/#ui2#cl_json.clas.abap index 58b42d30..6432cd2e 100644 --- a/src/json/#ui2#cl_json.clas.abap +++ b/src/json/#ui2#cl_json.clas.abap @@ -116,12 +116,14 @@ CLASS /ui2/cl_json IMPLEMENTATION. ELSEIF data IS INITIAL. r_json = '""'. ELSE. - r_json = '"' && escape( val = |{ data }| format = cl_abap_format=>e_json_string ) && '"'. + r_json = '"' && escape( val = |{ data }| + format = cl_abap_format=>e_json_string ) && '"'. ENDIF. WHEN cl_abap_typedescr=>typekind_xstring. r_json = '"' && cl_http_utility=>encode_x_base64( data ) && '"'. WHEN cl_abap_typedescr=>typekind_string. - r_json = '"' && escape( val = data format = cl_abap_format=>e_json_string ) && '"'. + r_json = '"' && escape( val = data + format = cl_abap_format=>e_json_string ) && '"'. WHEN cl_abap_typedescr=>typekind_int. r_json = |{ data }|. WHEN cl_abap_typedescr=>typekind_num. @@ -191,7 +193,9 @@ CLASS /ui2/cl_json IMPLEMENTATION. r_json = r_json && ','. ENDLOOP. IF r_json CP '*,'. - r_json = substring( val = r_json off = 0 len = strlen( r_json ) - 1 ). + r_json = substring( val = r_json + off = 0 + len = strlen( r_json ) - 1 ). ENDIF. r_json = r_json && '}'. WHEN cl_abap_typedescr=>kind_ref. diff --git a/src/kernel/call_transformation/kernel_call_transformation.clas.locals_imp.abap b/src/kernel/call_transformation/kernel_call_transformation.clas.locals_imp.abap index 8a25be98..6930e2e7 100644 --- a/src/kernel/call_transformation/kernel_call_transformation.clas.locals_imp.abap +++ b/src/kernel/call_transformation/kernel_call_transformation.clas.locals_imp.abap @@ -284,7 +284,8 @@ CLASS lcl_object_to_sxml IMPLEMENTATION. WRITE '@KERNEL result.assign(INPUT.source[name]);'. WRITE '@KERNEL }'. mi_writer->open_element( name = 'str' ). - mi_writer->write_attribute( name = 'name' value = to_upper( lv_name ) ). + mi_writer->write_attribute( name = 'name' + value = to_upper( lv_name ) ). traverse_write( result ). mi_writer->close_element( ). WRITE '@KERNEL }'. @@ -334,7 +335,8 @@ CLASS lcl_object_to_sxml IMPLEMENTATION. ASSIGN COMPONENT ls_compo-name OF STRUCTURE TO . GET REFERENCE OF INTO lv_ref. mi_writer->open_element( name = traverse_write_type( lv_ref ) ). - mi_writer->write_attribute( name = 'name' value = to_upper( ls_compo-name ) ). + mi_writer->write_attribute( name = 'name' + value = to_upper( ls_compo-name ) ). traverse_write( lv_ref ). mi_writer->close_element( ). ENDLOOP. diff --git a/src/sxml/cl_sxml_string_reader.clas.locals_imp.abap b/src/sxml/cl_sxml_string_reader.clas.locals_imp.abap index ac1b47a9..a7a0b3ff 100644 --- a/src/sxml/cl_sxml_string_reader.clas.locals_imp.abap +++ b/src/sxml/cl_sxml_string_reader.clas.locals_imp.abap @@ -89,9 +89,11 @@ CLASS lcl_json_parser IMPLEMENTATION. CASE lv_type. WHEN 'object'. - traverse_object( iv_json = iv_json iv_key = iv_key ). + traverse_object( iv_json = iv_json + iv_key = iv_key ). WHEN 'array'. - traverse_array( iv_json = iv_json iv_key = iv_key ). + traverse_array( iv_json = iv_json + iv_key = iv_key ). WHEN 'string' OR 'boolean' OR 'number' OR 'null'. WRITE '@KERNEL iv_json = iv_json.value + "";'. diff --git a/src/sxml/cl_sxml_string_writer.clas.testclasses.abap b/src/sxml/cl_sxml_string_writer.clas.testclasses.abap index 595a0ba8..567b7b7c 100644 --- a/src/sxml/cl_sxml_string_writer.clas.testclasses.abap +++ b/src/sxml/cl_sxml_string_writer.clas.testclasses.abap @@ -24,7 +24,8 @@ CLASS ltcl_json IMPLEMENTATION. intf ?= writer. intf->open_element( name = 'object' ). intf->open_element( name = 'str' ). - intf->write_attribute( name = 'name' value = 'text' ). + intf->write_attribute( name = 'name' + value = 'text' ). intf->write_value( 'moo' ). intf->close_element( ). intf->close_element( ). @@ -97,11 +98,13 @@ CLASS ltcl_json IMPLEMENTATION. intf ?= writer. intf->open_element( name = 'object' ). intf->open_element( name = 'str' ). - intf->write_attribute( name = 'name' value = 'text' ). + intf->write_attribute( name = 'name' + value = 'text' ). intf->write_value( 'moo' ). intf->close_element( ). intf->open_element( name = 'str' ). - intf->write_attribute( name = 'name' value = 'next' ). + intf->write_attribute( name = 'name' + value = 'next' ). intf->write_value( 'moo' ). intf->close_element( ). intf->close_element( ). diff --git a/src/unit/cl_abap_unit_assert.clas.testclasses.abap b/src/unit/cl_abap_unit_assert.clas.testclasses.abap index 39b64517..d75c1c3e 100644 --- a/src/unit/cl_abap_unit_assert.clas.testclasses.abap +++ b/src/unit/cl_abap_unit_assert.clas.testclasses.abap @@ -118,12 +118,16 @@ CLASS ltcl_test IMPLEMENTATION. METHOD equals. DATA bar TYPE i. - cl_abap_unit_assert=>assert_equals( act = bar exp = bar ). + cl_abap_unit_assert=>assert_equals( act = bar + exp = bar ). bar = 2. - cl_abap_unit_assert=>assert_equals( act = bar exp = bar ). + cl_abap_unit_assert=>assert_equals( act = bar + exp = bar ). - cl_abap_unit_assert=>assert_equals( act = 2 exp = 2 ). - cl_abap_unit_assert=>assert_equals( act = 'hello' exp = 'hello' ). + cl_abap_unit_assert=>assert_equals( act = 2 + exp = 2 ). + cl_abap_unit_assert=>assert_equals( act = 'hello' + exp = 'hello' ). ENDMETHOD. METHOD equals_date. diff --git a/test/adbc/init.sql b/test/adbc/init.sql new file mode 100644 index 00000000..b79a5f0b --- /dev/null +++ b/test/adbc/init.sql @@ -0,0 +1,9 @@ +CREATE TABLE films ( + code char(5), + title varchar(40), + did integer, + date_prod date, + kind varchar(10), + len interval hour to minute, + CONSTRAINT code_title PRIMARY KEY(code,title) +); \ No newline at end of file diff --git a/test/adbc/zcl_adbc_test.clas.abap b/test/adbc/zcl_adbc_test.clas.abap new file mode 100644 index 00000000..5fa67593 --- /dev/null +++ b/test/adbc/zcl_adbc_test.clas.abap @@ -0,0 +1,7 @@ +CLASS zcl_adbc_test DEFINITION PUBLIC. + PUBLIC SECTION. +ENDCLASS. + +CLASS zcl_adbc_test IMPLEMENTATION. + +ENDCLASS. \ No newline at end of file diff --git a/test/adbc/zcl_adbc_test.clas.testclasses.abap b/test/adbc/zcl_adbc_test.clas.testclasses.abap new file mode 100644 index 00000000..bd29af79 --- /dev/null +++ b/test/adbc/zcl_adbc_test.clas.testclasses.abap @@ -0,0 +1,22 @@ +CLASS ltcl_test DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION MEDIUM FINAL. + + PRIVATE SECTION. + METHODS test FOR TESTING RAISING cx_static_check. + +ENDCLASS. + +CLASS ltcl_test IMPLEMENTATION. + METHOD test. + + DATA lo_stmt TYPE REF TO cl_sql_statement. + DATA lv_sql TYPE string. + DATA lo_result TYPE REF TO cl_sql_result_set. + + + lo_stmt = cl_sql_connection=>get_abap_connection( 'PG' )->create_statement( ). + + lv_sql = |select * from films|. + lo_result = lo_stmt->execute_query( lv_sql ). + + ENDMETHOD. +ENDCLASS. \ No newline at end of file diff --git a/test/cl_http_client.clas.testclasses.abap b/test/cl_http_client.clas.testclasses.abap index 2d4f7470..d22bbaf0 100644 --- a/test/cl_http_client.clas.testclasses.abap +++ b/test/cl_http_client.clas.testclasses.abap @@ -136,7 +136,8 @@ CLASS ltcl_test IMPLEMENTATION. IMPORTING client = li_client ). - li_client->authenticate( username = 'sdf' password = 'sdf' ). + li_client->authenticate( username = 'sdf' + password = 'sdf' ). li_client->send( ). li_client->receive( ). @@ -177,11 +178,13 @@ CLASS ltcl_test IMPLEMENTATION. ASSERT li_client->request->get_method( ) = ''. ASSERT li_client->request->get_header_field( 'sdfds' ) = ''. - li_client->authenticate( username = 'sdf' password = 'sdf' ). + li_client->authenticate( username = 'sdf' + password = 'sdf' ). ASSERT li_client->request->get_header_field( 'Authorization' ) = 'Basic c2RmOnNkZg=='. ASSERT li_client->request->get_header_field( 'authorizaTION' ) = 'Basic c2RmOnNkZg=='. - li_client->request->set_header_field( name = 'FOObar' value = '42' ). + li_client->request->set_header_field( name = 'FOObar' + value = '42' ). li_client->request->get_header_fields( CHANGING fields = fields ). ASSERT lines( fields ) = 3. @@ -223,7 +226,8 @@ CLASS ltcl_test IMPLEMENTATION. ssl_id = 'ANONYM' IMPORTING client = li_client ). - li_client->request->set_form_field( name = 'foo' value = 'bar' ). + li_client->request->set_form_field( name = 'foo' + value = 'bar' ). li_client->send( ). li_client->receive( ). @@ -357,7 +361,8 @@ CLASS ltcl_test IMPLEMENTATION. ssl_id = 'ANONYM' IMPORTING client = li_client ). - li_client->request->set_header_field( name = '~request_uri' value = lv_uri ). + li_client->request->set_header_field( name = '~request_uri' + value = lv_uri ). lv_val = li_client->request->get_header_field( name = '~request_uri' ). cl_abap_unit_assert=>assert_equals( act = lv_uri @@ -398,8 +403,10 @@ CLASS ltcl_test IMPLEMENTATION. IMPORTING client = li_client ). li_client->request->set_method( 'POST' ). - li_client->request->set_form_field( name = 'foo1' value = 'bar1' ). - li_client->request->set_form_field( name = 'foo2' value = 'bar2' ). + li_client->request->set_form_field( name = 'foo1' + value = 'bar1' ). + li_client->request->set_form_field( name = 'foo2' + value = 'bar2' ). li_client->request->set_content_type( 'application/x-www-form-urlencoded' ). li_client->send( ). diff --git a/test/setup.mjs b/test/setup.mjs index e87b65f4..336d9efc 100644 --- a/test/setup.mjs +++ b/test/setup.mjs @@ -1,8 +1,19 @@ import {SQLiteDatabaseClient} from "@abaplint/database-sqlite"; +import {PostgresDatabaseClient} from "@abaplint/database-pg"; export async function setup(abap, schemas, insert) { abap.context.databaseConnections["DEFAULT"] = new SQLiteDatabaseClient(); await abap.context.databaseConnections["DEFAULT"].connect(); await abap.context.databaseConnections["DEFAULT"].execute(schemas.sqlite); await abap.context.databaseConnections["DEFAULT"].execute(insert); + + abap.context.databaseConnections["PG"] = new PostgresDatabaseClient({ + user: "postgres", + host: "localhost", + database: "postgres", + password: "postgres", + port: 5432, +// trace: true, + lazy: true, + }); } \ No newline at end of file diff --git a/test/stack.yml b/test/stack.yml new file mode 100644 index 00000000..6b89fcb0 --- /dev/null +++ b/test/stack.yml @@ -0,0 +1,21 @@ +services: + postgresql: + image: postgres:17 + container_name: postgresql + restart: always + environment: + POSTGRES_PASSWORD: postgres + ports: + - '5432:5432' + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 1s + timeout: 20s + retries: 5 + tmpfs: + - /var/lib/postgresql/data + httpbin: + image: kennethreitz/httpbin + container_name: httpbin + ports: + - '8080:80' \ No newline at end of file