holado 0.13.22__py3-none-any.whl
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.
- holado/__init__.py +358 -0
- holado/common/__init__.py +25 -0
- holado/common/context/__init__.py +25 -0
- holado/common/context/context.py +248 -0
- holado/common/context/service_manager.py +262 -0
- holado/common/context/session_context.py +516 -0
- holado/common/handlers/__init__.py +19 -0
- holado/common/handlers/enums.py +41 -0
- holado/common/handlers/object.py +175 -0
- holado/common/handlers/undefined.py +55 -0
- holado/common/tools/__init__.py +19 -0
- holado/common/tools/gc_manager.py +155 -0
- holado/holado_config.py +45 -0
- holado-0.13.22.dist-info/METADATA +194 -0
- holado-0.13.22.dist-info/RECORD +698 -0
- holado-0.13.22.dist-info/WHEEL +4 -0
- holado-0.13.22.dist-info/licenses/LICENSE +21 -0
- holado_ais/__init__.py +33 -0
- holado_ais/ais/MaritimeIdentificationDigits.csv +295 -0
- holado_ais/ais/ais_manager.py +151 -0
- holado_ais/ais/ais_messages.py +356 -0
- holado_ais/ais/ais_payload.py +35 -0
- holado_ais/ais/enums.py +37 -0
- holado_ais/ais/patch_pyais.py +1174 -0
- holado_ais/tests/behave/steps/__init__.py +17 -0
- holado_ais/tests/behave/steps/ais/__init__.py +0 -0
- holado_ais/tests/behave/steps/ais/ais_manager_steps.py +50 -0
- holado_ais/tests/behave/steps/ais/ais_messages_steps.py +237 -0
- holado_binary/__init__.py +17 -0
- holado_binary/ipc/binary.py +125 -0
- holado_binary/ipc/bit_series.py +307 -0
- holado_binary/tests/behave/steps/__init__.py +17 -0
- holado_binary/tests/behave/steps/ipc/binary_steps.py +57 -0
- holado_binary/tests/behave/steps/ipc/bit_series_steps.py +132 -0
- holado_context/__init__.py +16 -0
- holado_context/tests/behave/steps/__init__.py +16 -0
- holado_context/tests/behave/steps/private/__init__.py +16 -0
- holado_context/tests/behave/steps/private/common/context_steps.py +68 -0
- holado_core/__init__.py +32 -0
- holado_core/common/__init__.py +0 -0
- holado_core/common/actors/actions.py +97 -0
- holado_core/common/actors/actor.py +226 -0
- holado_core/common/actors/element_actor.py +32 -0
- holado_core/common/actors/find_actor.py +106 -0
- holado_core/common/actors/tree_actor.py +32 -0
- holado_core/common/actors/verify_actions.py +69 -0
- holado_core/common/block/base.py +122 -0
- holado_core/common/block/block_manager.py +173 -0
- holado_core/common/block/block_method.py +46 -0
- holado_core/common/block/block_steps.py +37 -0
- holado_core/common/block/function.py +42 -0
- holado_core/common/block/scope_function.py +28 -0
- holado_core/common/block/scope_manager.py +238 -0
- holado_core/common/block/scope_steps.py +141 -0
- holado_core/common/criterias/and_criteria.py +61 -0
- holado_core/common/criterias/criteria.py +78 -0
- holado_core/common/criterias/or_criteria.py +64 -0
- holado_core/common/criterias/tools/criteria_context.py +20 -0
- holado_core/common/criterias/tools/criteria_parameters.py +18 -0
- holado_core/common/drivers/driver.py +153 -0
- holado_core/common/drivers/element_driver.py +30 -0
- holado_core/common/drivers/element_internal_api.py +239 -0
- holado_core/common/drivers/internal_api.py +40 -0
- holado_core/common/drivers/tree_driver.py +30 -0
- holado_core/common/drivers/tree_internal_api.py +176 -0
- holado_core/common/exceptions/__init__.py +0 -0
- holado_core/common/exceptions/element_exception.py +28 -0
- holado_core/common/exceptions/exceptions.py +24 -0
- holado_core/common/exceptions/functional_exception.py +21 -0
- holado_core/common/exceptions/holado_exception.py +25 -0
- holado_core/common/exceptions/technical_exception.py +27 -0
- holado_core/common/exceptions/timeout_exception.py +20 -0
- holado_core/common/exceptions/verify_exception.py +20 -0
- holado_core/common/finders/after_in_tree_finder.py +87 -0
- holado_core/common/finders/element_finder.py +60 -0
- holado_core/common/finders/else_finder.py +105 -0
- holado_core/common/finders/finder.py +478 -0
- holado_core/common/finders/or_finder.py +98 -0
- holado_core/common/finders/then_finder.py +157 -0
- holado_core/common/finders/tools/enums.py +30 -0
- holado_core/common/finders/tools/find_builder.py +118 -0
- holado_core/common/finders/tools/find_context.py +405 -0
- holado_core/common/finders/tools/find_info.py +27 -0
- holado_core/common/finders/tools/find_parameters.py +240 -0
- holado_core/common/finders/tools/find_updater.py +95 -0
- holado_core/common/finders/tools/finder_info.py +26 -0
- holado_core/common/finders/tree_finder.py +146 -0
- holado_core/common/handlers/__init__.py +0 -0
- holado_core/common/handlers/abstracts/base_redo.py +702 -0
- holado_core/common/handlers/abstracts/get_or_create.py +120 -0
- holado_core/common/handlers/element_holder.py +122 -0
- holado_core/common/handlers/enums.py +23 -0
- holado_core/common/handlers/exceptions/redo_exceptions.py +28 -0
- holado_core/common/handlers/features/resource_by_name.py +187 -0
- holado_core/common/handlers/features/resource_by_type.py +174 -0
- holado_core/common/handlers/redo.py +119 -0
- holado_core/common/handlers/wait.py +127 -0
- holado_core/common/inspectors/element_inspector.py +57 -0
- holado_core/common/inspectors/inspector.py +221 -0
- holado_core/common/inspectors/tools/inspect_builder.py +169 -0
- holado_core/common/inspectors/tools/inspect_context.py +69 -0
- holado_core/common/inspectors/tools/inspect_parameters.py +181 -0
- holado_core/common/inspectors/tree_inspector.py +73 -0
- holado_core/common/resource/persisted_data_manager.py +113 -0
- holado_core/common/resource/persisted_method_to_call_manager.py +263 -0
- holado_core/common/resource/resource_manager.py +126 -0
- holado_core/common/resource/table_data_manager.py +110 -0
- holado_core/common/tables/__init__.py +1 -0
- holado_core/common/tables/comparators/__init__.py +0 -0
- holado_core/common/tables/comparators/boolean_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/bytes_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/datetime_table_cell_comparator.py +24 -0
- holado_core/common/tables/comparators/float_table_cell_comparator.py +31 -0
- holado_core/common/tables/comparators/integer_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/internal_table_cell_comparator.py +30 -0
- holado_core/common/tables/comparators/string_table_cell_comparator.py +24 -0
- holado_core/common/tables/comparators/string_table_comparator.py +29 -0
- holado_core/common/tables/comparators/string_table_row_comparator.py +29 -0
- holado_core/common/tables/comparators/table_cell_comparator.py +40 -0
- holado_core/common/tables/comparators/table_comparator.py +209 -0
- holado_core/common/tables/comparators/table_comparator_manager.py +60 -0
- holado_core/common/tables/comparators/table_row_comparator.py +116 -0
- holado_core/common/tables/comparators/table_with_header_comparator.py +68 -0
- holado_core/common/tables/converters/__init__.py +0 -0
- holado_core/common/tables/converters/table_converter.py +233 -0
- holado_core/common/tables/enums.py +23 -0
- holado_core/common/tables/table.py +261 -0
- holado_core/common/tables/table_cell.py +126 -0
- holado_core/common/tables/table_manager.py +365 -0
- holado_core/common/tables/table_row.py +169 -0
- holado_core/common/tables/table_with_header.py +242 -0
- holado_core/common/tools/__init__.py +0 -0
- holado_core/common/tools/comparators/comparator.py +151 -0
- holado_core/common/tools/comparators/object_comparator.py +21 -0
- holado_core/common/tools/converters/converter.py +118 -0
- holado_core/common/tools/path_manager.py +238 -0
- holado_core/common/tools/string_tools.py +144 -0
- holado_core/common/tools/tools.py +197 -0
- holado_core/tests/behave/steps/__init__.py +20 -0
- holado_core/tests/behave/steps/common/__init__.py +0 -0
- holado_core/tests/behave/steps/common/common_steps.py +137 -0
- holado_core/tests/behave/steps/common/config_steps.py +42 -0
- holado_core/tests/behave/steps/common/resource_steps.py +62 -0
- holado_core/tests/behave/steps/common/tables_steps.py +560 -0
- holado_core/tools/__init__.py +0 -0
- holado_core/tools/abstracts/__init__.py +0 -0
- holado_core/tools/abstracts/blocking_command_service.py +64 -0
- holado_core/tools/abstracts/service.py +48 -0
- holado_crypto/__init__.py +31 -0
- holado_crypto/crypto/crypto.py +108 -0
- holado_crypto/crypto/key.py +92 -0
- holado_crypto/crypto/tcpbin.py +105 -0
- holado_crypto/crypto/transport/__init__.py +0 -0
- holado_crypto/crypto/transport/crc.py +40 -0
- holado_crypto/tests/behave/steps/__init__.py +18 -0
- holado_crypto/tests/behave/steps/crypto_steps.py +112 -0
- holado_crypto/tests/behave/steps/key_steps.py +82 -0
- holado_crypto/tests/behave/steps/tcpbin_steps.py +79 -0
- holado_data/__init__.py +31 -0
- holado_data/data/generator/base.py +93 -0
- holado_data/data/generator/generator_manager.py +27 -0
- holado_data/data/generator/python_generator.py +30 -0
- holado_data/tests/behave/steps/__init__.py +17 -0
- holado_data/tests/behave/steps/data/generator_steps.py +91 -0
- holado_data/tests/behave/steps/tools/utils_steps.py +59 -0
- holado_db/__init__.py +32 -0
- holado_db/tests/behave/steps/__init__.py +18 -0
- holado_db/tests/behave/steps/tools/db/db_client_steps.py +134 -0
- holado_db/tests/behave/steps/tools/db/postgresql_client_steps.py +59 -0
- holado_db/tests/behave/steps/tools/db/sqlite_client_steps.py +57 -0
- holado_db/tools/db/clients/base/db_audit.py +94 -0
- holado_db/tools/db/clients/base/db_client.py +344 -0
- holado_db/tools/db/clients/postgresql/postgresql_audit.py +75 -0
- holado_db/tools/db/clients/postgresql/postgresql_client.py +84 -0
- holado_db/tools/db/clients/sqlite/sqlite_audit.py +70 -0
- holado_db/tools/db/clients/sqlite/sqlite_client.py +60 -0
- holado_db/tools/db/db_manager.py +109 -0
- holado_db/tools/db/query/base/query_builder.py +138 -0
- holado_db/tools/db/query/pypika/pypika_query_builder.py +244 -0
- holado_db/tools/db/query/query_manager.py +77 -0
- holado_django/__init__.py +31 -0
- holado_django/server/HOWTO.txt +27 -0
- holado_django/server/django_projects/rest_api/db.sqlite3 +0 -0
- holado_django/server/django_projects/rest_api/manage.py +22 -0
- holado_django/server/django_projects/rest_api/rest_api/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/admin.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/apps.py +9 -0
- holado_django/server/django_projects/rest_api/rest_api/application/migrations/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/models.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/tests.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/views.py +6 -0
- holado_django/server/django_projects/rest_api/rest_api/asgi.py +16 -0
- holado_django/server/django_projects/rest_api/rest_api/settings.py +130 -0
- holado_django/server/django_projects/rest_api/rest_api/urls.py +35 -0
- holado_django/server/django_projects/rest_api/rest_api/wsgi.py +16 -0
- holado_django/server/django_server.py +110 -0
- holado_django/server/grpc_django_server.py +57 -0
- holado_django/server/patch_djangogrpcframework.py +46 -0
- holado_django/tests/behave/steps/__init__.py +16 -0
- holado_django/tests/behave/steps/django_server_steps.py +83 -0
- holado_docker/__init__.py +25 -0
- holado_docker/sdk/docker/container_logs.py +447 -0
- holado_docker/sdk/docker/docker_client.py +537 -0
- holado_docker/sdk/docker/docker_service.py +71 -0
- holado_docker/tests/behave/steps/__init__.py +16 -0
- holado_docker/tests/behave/steps/sdk/docker/container_logs_steps.py +47 -0
- holado_examples/projects/server_rest/server_rest_example/initialize_holado.py +72 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/db.sqlite3 +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/manage.py +22 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/admin.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/apps.py +7 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/migrations/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/models.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/serializers.py +15 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/tests.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/views.py +24 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/asgi.py +16 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/settings.py +130 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/urls.py +31 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/wsgi.py +16 -0
- holado_examples/projects/server_rest/server_rest_example/rest_server.py +37 -0
- holado_examples/scripts/script_custom_initialization.py +16 -0
- holado_examples/scripts/script_minimal_initialization.py +23 -0
- holado_examples/tests/behave/testing_solution/__main__.py +13 -0
- holado_examples/tests/behave/testing_solution/behave_environment.py +35 -0
- holado_examples/tests/behave/testing_solution/environment.py +36 -0
- holado_examples/tests/behave/testing_solution/features/Configuration/Actions/configure_system.feature +10 -0
- holado_examples/tests/behave/testing_solution/features/NonReg/example.feature +26 -0
- holado_examples/tests/behave/testing_solution/initialize_holado.py +62 -0
- holado_examples/tests/behave/testing_solution/logging.conf +102 -0
- holado_examples/tests/behave/testing_solution/requirements.txt +5 -0
- holado_examples/tests/behave/testing_solution/run_test.sh +7 -0
- holado_examples/tests/behave/testing_solution/run_test_nonreg.sh +6 -0
- holado_examples/tests/behave/testing_solution/src/common/tools/path_manager.py +40 -0
- holado_examples/tests/behave/testing_solution/src/config/config_manager.py +30 -0
- holado_examples/tests/behave/testing_solution/src/context/session_context.py +45 -0
- holado_examples/tests/behave/testing_solution/steps/config_steps.py +21 -0
- holado_examples/tests/behave/testing_solution/steps/public_steps.py +10 -0
- holado_grpc/TODO +8 -0
- holado_grpc/__init__.py +40 -0
- holado_grpc/api/rpc/TODO.txt +4 -0
- holado_grpc/api/rpc/grpc_client.py +210 -0
- holado_grpc/api/rpc/grpc_manager.py +81 -0
- holado_grpc/ipc/rpc/__init__.py +0 -0
- holado_grpc/ipc/rpc/grpc_compiler.py +45 -0
- holado_grpc/ipc/rpc/grpc_services.py +165 -0
- holado_grpc/tests/behave/steps/__init__.py +16 -0
- holado_grpc/tests/behave/steps/api/grpc_client_steps.py +173 -0
- holado_grpc/tests/behave/steps/private/__init__.py +16 -0
- holado_grpc/tests/behave/steps/private/api/grpc_steps.py +77 -0
- holado_helper/__init__.py +35 -0
- holado_helper/debug/README.txt +32 -0
- holado_helper/debug/memory/memory_profiler.py +106 -0
- holado_helper/docker/init_user.sh +24 -0
- holado_helper/docker/logging.conf +44 -0
- holado_helper/docker/run_holado_test_nonreg_in_docker.sh +120 -0
- holado_helper/docker/run_terminal_in_docker.sh +101 -0
- holado_helper/holado_module_template/__init__.py +38 -0
- holado_helper/holado_module_template/tests/behave/steps/__init__.py +16 -0
- holado_helper/holado_module_template/tests/behave/steps/private/__init__.py +16 -0
- holado_helper/initialize_holado.py +72 -0
- holado_helper/script/action.py +130 -0
- holado_helper/script/action_script.py +477 -0
- holado_helper/script/any_action_script.py +126 -0
- holado_helper/script/behave_action_script.py +99 -0
- holado_helper/script/csv_action_script.py +142 -0
- holado_helper/script/initialize_script.py +95 -0
- holado_helper/script/input_output_script.py +136 -0
- holado_helper/script/job.py +75 -0
- holado_helper/script/json_action_script.py +104 -0
- holado_helper/script/script.py +110 -0
- holado_json/__init__.py +16 -0
- holado_json/filesystem/json_file.py +94 -0
- holado_json/filesystem/stream_json_file.py +117 -0
- holado_json/ipc/json.py +146 -0
- holado_json/ipc/json_converter.py +69 -0
- holado_json/ipc/json_types.py +183 -0
- holado_json/tests/behave/steps/__init__.py +16 -0
- holado_json/tests/behave/steps/ipc/__init__.py +0 -0
- holado_json/tests/behave/steps/ipc/json_steps.py +131 -0
- holado_keycloak/__init__.py +16 -0
- holado_keycloak/tests/behave/steps/__init__.py +16 -0
- holado_keycloak/tests/behave/steps/tools/keycloak_client_steps.py +73 -0
- holado_keycloak/tools/keycloak/__init__.py +0 -0
- holado_keycloak/tools/keycloak/keycloak_client.py +90 -0
- holado_logging/__init__.py +38 -0
- holado_logging/common/logging/holado_logger.py +71 -0
- holado_logging/common/logging/log_config.py +163 -0
- holado_logging/common/logging/log_manager.py +335 -0
- holado_multitask/__init__.py +33 -0
- holado_multitask/multiprocessing/context/process_context.py +35 -0
- holado_multitask/multiprocessing/function_process.py +102 -0
- holado_multitask/multiprocessing/periodic_function_process.py +137 -0
- holado_multitask/multiprocessing/process.py +213 -0
- holado_multitask/multiprocessing/processesmanager.py +137 -0
- holado_multitask/multitasking/multitask_manager.py +464 -0
- holado_multitask/multithreading/__init__.py +0 -0
- holado_multitask/multithreading/context/thread_context.py +86 -0
- holado_multitask/multithreading/functionthreaded.py +129 -0
- holado_multitask/multithreading/loopfunctionthreaded.py +45 -0
- holado_multitask/multithreading/loopthread.py +110 -0
- holado_multitask/multithreading/periodicfunctionthreaded.py +135 -0
- holado_multitask/multithreading/reflection/inspect.py +47 -0
- holado_multitask/multithreading/reflection/sys.py +29 -0
- holado_multitask/multithreading/reflection/traceback.py +35 -0
- holado_multitask/multithreading/thread.py +203 -0
- holado_multitask/multithreading/threadsmanager.py +167 -0
- holado_multitask/multithreading/timer.py +51 -0
- holado_multitask/tests/behave/steps/__init__.py +17 -0
- holado_multitask/tests/behave/steps/multiprocessing_steps.py +138 -0
- holado_multitask/tests/behave/steps/multithreading_steps.py +129 -0
- holado_protobuf/__init__.py +61 -0
- holado_protobuf/ipc/protobuf/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/abstracts/type.py +45 -0
- holado_protobuf/ipc/protobuf/protobuf_compiler.py +118 -0
- holado_protobuf/ipc/protobuf/protobuf_converter.py +153 -0
- holado_protobuf/ipc/protobuf/protobuf_messages.py +968 -0
- holado_protobuf/ipc/protobuf/protobuf_modifier.py +65 -0
- holado_protobuf/ipc/protobuf/types/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/types/google/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/types/google/protobuf.py +124 -0
- holado_protobuf/tests/behave/steps/__init__.py +16 -0
- holado_protobuf/tests/behave/steps/ipc/protobuf_steps.py +297 -0
- holado_python/__init__.py +36 -0
- holado_python/common/enums.py +34 -0
- holado_python/common/iterables.py +38 -0
- holado_python/common/tools/comparators/boolean_comparator.py +37 -0
- holado_python/common/tools/comparators/bytes_comparator.py +48 -0
- holado_python/common/tools/comparators/datetime_comparator.py +74 -0
- holado_python/common/tools/comparators/float_comparator.py +97 -0
- holado_python/common/tools/comparators/integer_comparator.py +37 -0
- holado_python/common/tools/comparators/string_comparator.py +99 -0
- holado_python/common/tools/comparators/type_comparator.py +31 -0
- holado_python/common/tools/datetime.py +341 -0
- holado_python/standard_library/csv.py +207 -0
- holado_python/standard_library/hashlib.py +110 -0
- holado_python/standard_library/multiprocessing.py +62 -0
- holado_python/standard_library/queue.py +79 -0
- holado_python/standard_library/socket/blocking_socket.py +219 -0
- holado_python/standard_library/socket/echo_server.py +29 -0
- holado_python/standard_library/socket/message_socket.py +152 -0
- holado_python/standard_library/socket/non_blocking_socket.py +172 -0
- holado_python/standard_library/socket/socket.py +411 -0
- holado_python/standard_library/ssl/resources/certificates/NOTES.txt +5 -0
- holado_python/standard_library/ssl/resources/certificates/localhost.crt +19 -0
- holado_python/standard_library/ssl/resources/certificates/localhost.key +28 -0
- holado_python/standard_library/ssl/ssl.py +131 -0
- holado_python/standard_library/typing.py +192 -0
- holado_python/tests/behave/steps/__init__.py +27 -0
- holado_python/tests/behave/steps/builtins/str_steps.py +45 -0
- holado_python/tests/behave/steps/convert_steps.py +59 -0
- holado_python/tests/behave/steps/iterable_steps.py +87 -0
- holado_python/tests/behave/steps/standard_library/csv_steps.py +134 -0
- holado_python/tests/behave/steps/standard_library/datetime_steps.py +163 -0
- holado_python/tests/behave/steps/standard_library/hashlib_steps.py +57 -0
- holado_python/tests/behave/steps/standard_library/multiprocessing_steps.py +56 -0
- holado_python/tests/behave/steps/standard_library/queue_steps.py +358 -0
- holado_python/tests/behave/steps/standard_library/socket_steps.py +384 -0
- holado_python/tests/behave/steps/standard_library/ssl_steps.py +71 -0
- holado_rabbitmq/__init__.py +28 -0
- holado_rabbitmq/tests/behave/steps/__init__.py +17 -0
- holado_rabbitmq/tests/behave/steps/tools/rabbitmq_client_steps.py +565 -0
- holado_rabbitmq/tests/behave/steps/tools/rabbitmq_server_steps.py +64 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_blocking_client.py +333 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_client.py +678 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_manager.py +146 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_select_client.py +428 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_server.py +24 -0
- holado_redis/__init__.py +17 -0
- holado_redis/tests/behave/steps/__init__.py +16 -0
- holado_redis/tests/behave/steps/tools/redis_client_steps.py +101 -0
- holado_redis/tools/redis/TODO.txt +7 -0
- holado_redis/tools/redis/redis_client.py +190 -0
- holado_redis/tools/redis/redis_manager.py +38 -0
- holado_report/__init__.py +36 -0
- holado_report/campaign/campaign_manager.py +348 -0
- holado_report/report/analyze/execution_historic_manager.py +96 -0
- holado_report/report/analyze/scenario_duration_manager.py +245 -0
- holado_report/report/builders/detailed_scenario_report_builder.py +172 -0
- holado_report/report/builders/execution_historic_report_builder.py +132 -0
- holado_report/report/builders/failure_report_builder.py +150 -0
- holado_report/report/builders/report_builder.py +64 -0
- holado_report/report/builders/short_scenario_report_builder.py +94 -0
- holado_report/report/builders/summary_by_category_report_builder.py +103 -0
- holado_report/report/builders/summary_report_builder.py +110 -0
- holado_report/report/builders/summary_scenario_by_category_report_builder.py +109 -0
- holado_report/report/builders/summary_scenario_report_builder.py +81 -0
- holado_report/report/execution_historic.py +144 -0
- holado_report/report/report_manager.py +424 -0
- holado_report/report/reports/base_report.py +163 -0
- holado_report/report/reports/feature_report.py +106 -0
- holado_report/report/reports/scenario_report.py +64 -0
- holado_rest/__init__.py +32 -0
- holado_rest/api/rest/TODO.txt +2 -0
- holado_rest/api/rest/rest_client.py +200 -0
- holado_rest/api/rest/rest_manager.py +72 -0
- holado_rest/tests/behave/steps/__init__.py +16 -0
- holado_rest/tests/behave/steps/api/__init__.py +0 -0
- holado_rest/tests/behave/steps/api/rest_client_steps.py +181 -0
- holado_rest/tests/behave/steps/private/__init__.py +16 -0
- holado_rest/tests/behave/steps/private/api/__init__.py +0 -0
- holado_rest/tests/behave/steps/private/api/rest_steps.py +75 -0
- holado_s3/__init__.py +17 -0
- holado_s3/tests/behave/steps/__init__.py +17 -0
- holado_s3/tests/behave/steps/private/__init__.py +16 -0
- holado_s3/tests/behave/steps/private/tools/s3_steps.py +89 -0
- holado_s3/tests/behave/steps/tools/s3_client_steps.py +403 -0
- holado_s3/tests/behave/steps/tools/s3_server_steps.py +57 -0
- holado_s3/tools/s3/__init__.py +0 -0
- holado_s3/tools/s3/boto3_s3_client.py +59 -0
- holado_s3/tools/s3/minio_client.py +75 -0
- holado_s3/tools/s3/moto_server.py +52 -0
- holado_scripting/__init__.py +54 -0
- holado_scripting/common/tools/dynamic_text_manager.py +73 -0
- holado_scripting/common/tools/evaluate_parameters.py +228 -0
- holado_scripting/common/tools/expression_evaluator.py +389 -0
- holado_scripting/common/tools/variable_manager.py +354 -0
- holado_scripting/tests/behave/steps/__init__.py +22 -0
- holado_scripting/tests/behave/steps/common/tools/variable_convert_steps.py +159 -0
- holado_scripting/tests/behave/steps/common/tools/variable_new_steps.py +130 -0
- holado_scripting/tests/behave/steps/common/tools/variable_steps.py +108 -0
- holado_scripting/tests/behave/steps/common/tools/variable_verify_steps.py +160 -0
- holado_scripting/tests/behave/steps/scenario/function_steps.py +77 -0
- holado_scripting/tests/behave/steps/scenario/if_steps.py +87 -0
- holado_scripting/tests/behave/steps/scenario/loop_steps.py +119 -0
- holado_scripting/text/base/base_function.py +25 -0
- holado_scripting/text/base/base_verify_function.py +25 -0
- holado_scripting/text/base/text_inspecter.py +204 -0
- holado_scripting/text/interpreter/exceptions/interpreter_exception.py +25 -0
- holado_scripting/text/interpreter/functions/function_apply_function.py +60 -0
- holado_scripting/text/interpreter/functions/function_cast.py +60 -0
- holado_scripting/text/interpreter/functions/function_convert.py +57 -0
- holado_scripting/text/interpreter/functions/function_dynamic_value.py +40 -0
- holado_scripting/text/interpreter/functions/function_escape_all_bytes.py +35 -0
- holado_scripting/text/interpreter/functions/function_exists_variable.py +39 -0
- holado_scripting/text/interpreter/functions/function_hex_to_bytes.py +49 -0
- holado_scripting/text/interpreter/functions/function_hex_to_int.py +53 -0
- holado_scripting/text/interpreter/functions/function_to_base_64.py +41 -0
- holado_scripting/text/interpreter/functions/function_to_bytes.py +50 -0
- holado_scripting/text/interpreter/functions/function_to_hex.py +42 -0
- holado_scripting/text/interpreter/functions/function_to_string.py +50 -0
- holado_scripting/text/interpreter/text_interpreter.py +219 -0
- holado_scripting/text/verifier/exceptions/verifier_exception.py +21 -0
- holado_scripting/text/verifier/functions/verify_function_extract_in.py +35 -0
- holado_scripting/text/verifier/functions/verify_function_match_pattern.py +63 -0
- holado_scripting/text/verifier/text_verifier.py +103 -0
- holado_sftp/__init__.py +16 -0
- holado_sftp/tests/behave/steps/__init__.py +17 -0
- holado_sftp/tests/behave/steps/private/__init__.py +16 -0
- holado_sftp/tests/behave/steps/private/tools/sftp_steps.py +78 -0
- holado_sftp/tests/behave/steps/tools/sftp_client_steps.py +94 -0
- holado_sftp/tests/behave/steps/tools/sftp_server_steps.py +82 -0
- holado_sftp/tools/sftp/__init__.py +0 -0
- holado_sftp/tools/sftp/sftp_client.py +103 -0
- holado_sftp/tools/sftp/sftp_server.py +39 -0
- holado_swagger/__init__.py +31 -0
- holado_swagger/swagger_hub/mockserver/mockserver_client.py +82 -0
- holado_swagger/swagger_hub/mockserver/mockserver_manager.py +33 -0
- holado_swagger/tests/behave/steps/__init__.py +16 -0
- holado_swagger/tests/behave/steps/swagger_hub/mockserver_steps.py +74 -0
- holado_system/system/command/command.py +247 -0
- holado_system/system/command/command_result.py +128 -0
- holado_system/system/command/curl_command.py +101 -0
- holado_system/system/command/exceptions.py +59 -0
- holado_system/system/filesystem/file.py +150 -0
- holado_system/system/global_system.py +187 -0
- holado_system/tests/behave/steps/__init__.py +18 -0
- holado_system/tests/behave/steps/system/commands_steps.py +92 -0
- holado_system/tests/behave/steps/system/file_steps.py +231 -0
- holado_system/tests/behave/steps/system/system_steps.py +84 -0
- holado_test/__init__.py +30 -0
- holado_test/behave/__init__.py +0 -0
- holado_test/behave/behave.py +400 -0
- holado_test/behave/behave_environment.py +169 -0
- holado_test/behave/behave_function.py +33 -0
- holado_test/behave/behave_manager.py +558 -0
- holado_test/behave/independant_runner.py +66 -0
- holado_test/behave/scenario/__init__.py +0 -0
- holado_test/behave/scenario/behave_step_tools.py +157 -0
- holado_test/common/context/feature_context.py +81 -0
- holado_test/common/context/scenario_context.py +169 -0
- holado_test/common/context/step_context.py +66 -0
- holado_test/common/exceptions/undefined_step_exception.py +21 -0
- holado_test/scenario/step_tools.py +547 -0
- holado_test/scenario/tester_tools.py +57 -0
- holado_test/test_config.py +26 -0
- holado_test/tests/behave/steps/__init__.py +18 -0
- holado_test/tests/behave/steps/scenario/exception_steps.py +87 -0
- holado_test/tests/behave/steps/scenario/scenario_steps.py +100 -0
- holado_test/tests/behave/steps/scenario/tester_steps.py +65 -0
- holado_test/tools/test_server/client/rest/test_server_client.py +150 -0
- holado_test/tools/test_server/server/Dockerfile +60 -0
- holado_test/tools/test_server/server/core/server_context.py +42 -0
- holado_test/tools/test_server/server/core/server_manager.py +41 -0
- holado_test/tools/test_server/server/requirements.txt +2 -0
- holado_test/tools/test_server/server/rest/README +2 -0
- holado_test/tools/test_server/server/rest/api/__init__.py +24 -0
- holado_test/tools/test_server/server/rest/api/campaign/__init__.py +32 -0
- holado_test/tools/test_server/server/rest/api/campaign/scenario.py +40 -0
- holado_test/tools/test_server/server/rest/initialize_holado.py +72 -0
- holado_test/tools/test_server/server/rest/logging.conf +51 -0
- holado_test/tools/test_server/server/rest/openapi.yaml +57 -0
- holado_test/tools/test_server/server/rest/run.py +41 -0
- holado_test/tools/test_server/server/run.sh +6 -0
- holado_test/tools/test_server/server/run_test_server_in_docker.sh +104 -0
- holado_tools/__init__.py +38 -0
- holado_tools/scripts/execute_persisted_post_processes/execute_persisted_post_processes.py +36 -0
- holado_tools/scripts/execute_persisted_post_processes/execute_persisted_post_processes.sh +6 -0
- holado_tools/scripts/execute_persisted_post_processes/initialize_holado.py +62 -0
- holado_tools/tests/behave/steps/__init__.py +16 -0
- holado_tools/tests/behave/steps/tools/host_controller/client_steps.py +97 -0
- holado_tools/tools/host_controller/client/rest/host_controller_client.py +275 -0
- holado_tools/tools/host_controller/server/Dockerfile +60 -0
- holado_tools/tools/host_controller/server/requirements.txt +2 -0
- holado_tools/tools/host_controller/server/rest/README +2 -0
- holado_tools/tools/host_controller/server/rest/api/__init__.py +24 -0
- holado_tools/tools/host_controller/server/rest/api/config.py +88 -0
- holado_tools/tools/host_controller/server/rest/api/docker/__init__.py +66 -0
- holado_tools/tools/host_controller/server/rest/api/docker/container.py +144 -0
- holado_tools/tools/host_controller/server/rest/api/docker/logs.py +66 -0
- holado_tools/tools/host_controller/server/rest/api/os.py +58 -0
- holado_tools/tools/host_controller/server/rest/initialize_holado.py +72 -0
- holado_tools/tools/host_controller/server/rest/openapi.yaml +561 -0
- holado_tools/tools/host_controller/server/rest/run.py +31 -0
- holado_tools/tools/host_controller/server/run_host_controller_in_docker.sh +107 -0
- holado_tools/tools/host_viewer/client/rest/host_viewer_client.py +190 -0
- holado_tools/tools/host_viewer/server/Dockerfile +60 -0
- holado_tools/tools/host_viewer/server/requirements.txt +2 -0
- holado_tools/tools/host_viewer/server/rest/README +2 -0
- holado_tools/tools/host_viewer/server/rest/api/__init__.py +24 -0
- holado_tools/tools/host_viewer/server/rest/api/docker/__init__.py +65 -0
- holado_tools/tools/host_viewer/server/rest/api/docker/container.py +87 -0
- holado_tools/tools/host_viewer/server/rest/api/os.py +58 -0
- holado_tools/tools/host_viewer/server/rest/initialize_holado.py +72 -0
- holado_tools/tools/host_viewer/server/rest/openapi.yaml +301 -0
- holado_tools/tools/host_viewer/server/rest/run.py +31 -0
- holado_tools/tools/host_viewer/server/run_host_viewer_in_docker.sh +107 -0
- holado_value/__init__.py +24 -0
- holado_value/common/tables/comparators/table_2_value_table_cell_comparator.py +196 -0
- holado_value/common/tables/comparators/table_2_value_table_comparator.py +27 -0
- holado_value/common/tables/comparators/table_2_value_table_row_comparator.py +27 -0
- holado_value/common/tables/comparators/table_2_value_table_with_header_comparator.py +27 -0
- holado_value/common/tables/converters/value_table_converter.py +267 -0
- holado_value/common/tables/value_table.py +29 -0
- holado_value/common/tables/value_table_cell.py +76 -0
- holado_value/common/tables/value_table_manager.py +48 -0
- holado_value/common/tables/value_table_row.py +43 -0
- holado_value/common/tables/value_table_with_header.py +28 -0
- holado_value/common/tools/unique_value_manager.py +109 -0
- holado_value/common/tools/value.py +191 -0
- holado_value/common/tools/value_types.py +41 -0
- holado_value/tests/behave/steps/__init__.py +16 -0
- holado_value/tests/behave/steps/private/__init__.py +16 -0
- holado_ws/__init__.py +16 -0
- holado_ws/api/ws/TODO.txt +2 -0
- holado_ws/tests/behave/steps/__init__.py +16 -0
- holado_ws/tests/behave/steps/api/web_service_steps.py +189 -0
- holado_xml/__init__.py +38 -0
- holado_xml/tests/behave/steps/__init__.py +16 -0
- holado_xml/tests/behave/steps/private/__init__.py +16 -0
- holado_xml/xml/stream_xml_file.py +181 -0
- holado_xml/xml/xml_file.py +97 -0
- holado_xml/xml/xml_manager.py +35 -0
- holado_yaml/__init__.py +31 -0
- holado_yaml/tests/behave/steps/__init__.py +16 -0
- holado_yaml/tests/behave/steps/yaml_steps.py +161 -0
- holado_yaml/yaml/enums.py +28 -0
- holado_yaml/yaml/pyyaml/pyyaml_client.py +72 -0
- holado_yaml/yaml/ruamel/ruamel_yaml_client.py +80 -0
- holado_yaml/yaml/yaml_client.py +203 -0
- holado_yaml/yaml/yaml_manager.py +94 -0
- test_holado/Dockerfile_test_holado +82 -0
- test_holado/__init__.py +4 -0
- test_holado/__main__.py +25 -0
- test_holado/build_docker_image_to_test_holado_in_docker.sh +7 -0
- test_holado/environment.py +60 -0
- test_holado/features/Configuration/Actions/execute_persisted_post_processes.feature +13 -0
- test_holado/features/NonReg/api/REST.feature +26 -0
- test_holado/features/NonReg/api/gRPC.feature +116 -0
- test_holado/features/NonReg/common/multiprocessing/simple.feature +60 -0
- test_holado/features/NonReg/common/system/commands.feature +43 -0
- test_holado/features/NonReg/common/system/system.feature +20 -0
- test_holado/features/NonReg/common/tables/table.feature +245 -0
- test_holado/features/NonReg/common/tables/value_table_conversion.feature +29 -0
- test_holado/features/NonReg/common/tools/DateTime.feature +88 -0
- test_holado/features/NonReg/common/tools/UniqueValueManager.feature +43 -0
- test_holado/features/NonReg/holado_ais/ais_message-bitarray_to_nmea.feature +135 -0
- test_holado/features/NonReg/holado_ais/ais_message-nmea_raw_to_dict.feature +93 -0
- test_holado/features/NonReg/holado_ais/message_types/type-10.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-12.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-14.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-15.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-16.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-17.feature +46 -0
- test_holado/features/NonReg/holado_ais/message_types/type-18.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-19.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-1_2_3.feature +42 -0
- test_holado/features/NonReg/holado_ais/message_types/type-20.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-21.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-22.feature +84 -0
- test_holado/features/NonReg/holado_ais/message_types/type-23.feature +49 -0
- test_holado/features/NonReg/holado_ais/message_types/type-24.feature +72 -0
- test_holado/features/NonReg/holado_ais/message_types/type-25.feature +143 -0
- test_holado/features/NonReg/holado_ais/message_types/type-26.feature +144 -0
- test_holado/features/NonReg/holado_ais/message_types/type-27.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-4_11.feature +39 -0
- test_holado/features/NonReg/holado_ais/message_types/type-5.feature +33 -0
- test_holado/features/NonReg/holado_ais/message_types/type-6.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-7_13.feature +43 -0
- test_holado/features/NonReg/holado_ais/message_types/type-8.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-9.feature +37 -0
- test_holado/features/NonReg/holado_binary/bit_series.error.feature +33 -0
- test_holado/features/NonReg/holado_binary/bit_series.feature +144 -0
- test_holado/features/NonReg/holado_protobuf/protobuf.feature +291 -0
- test_holado/features/NonReg/holado_python/convert.feature +20 -0
- test_holado/features/NonReg/holado_python/iterable.feature +61 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_reset.feature +191 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_with_tls_and_verify.feature +279 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_with_tls_without_verify.feature +299 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_without_tls.feature +163 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_with_mtls.feature +214 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_with_tls.feature +184 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_without_tls.feature +169 -0
- test_holado/features/NonReg/holado_scripting/common/tools/dynamic_text_manager.feature +18 -0
- test_holado/features/NonReg/holado_scripting/common/tools/expression_evaluator.feature +185 -0
- test_holado/features/NonReg/holado_scripting/common/tools/variable_manager.feature +71 -0
- test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.error.feature +21 -0
- test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.feature +120 -0
- test_holado/features/NonReg/holado_yaml/yaml.feature +514 -0
- test_holado/features/NonReg/ipc/json.feature +20 -0
- test_holado/features/NonReg/scenario/scenario.feature +183 -0
- test_holado/features/NonReg/test_steps/behave.feature +275 -0
- test_holado/features/NonReg/test_steps/common.feature +100 -0
- test_holado/features/NonReg/tools/RabbitMQ.feature +445 -0
- test_holado/features/NonReg/tools/RabbitMQ_steps.feature +276 -0
- test_holado/features/NonReg/tools/S3/boto3_client.feature +73 -0
- test_holado/features/NonReg/tools/S3/minio_client.feature +75 -0
- test_holado/features/NonReg/tools/db_sqlite3.feature +41 -0
- test_holado/features/NonReg/tools/sFTP.feature +25 -0
- test_holado/features/Test/logger.feature +28 -0
- test_holado/features/Test/test_host_controller.feature +13 -0
- test_holado/features/Test/test_parameter.feature +15 -0
- test_holado/features/__init__.py +0 -0
- test_holado/initialize_holado.py +62 -0
- test_holado/logging.conf +53 -0
- test_holado/resources/proto/definitions/protobuf/custom_types/field_types.proto +24 -0
- test_holado/resources/proto/definitions/protobuf/protobuf.dev/tutorial/addressbook.proto +56 -0
- test_holado/resources/proto/generated/protobuf/custom_types/field_types_pb2.py +34 -0
- test_holado/resources/proto/generated/protobuf/protobuf/dev/tutorial/addressbook_pb2.py +34 -0
- test_holado/resources/scripts/list_tags.sh +2 -0
- test_holado/resources/scripts/update_resources_proto_generated.py +70 -0
- test_holado/steps/__init__.py +0 -0
- test_holado/steps/private_steps.py +20 -0
- test_holado/steps/public_steps.py +23 -0
- test_holado/test_holado_session_context.py +43 -0
- test_holado/tools/connexion/api_rest/openapi.yaml +16 -0
- test_holado/tools/connexion/api_rest/run.py +19 -0
- test_holado/tools/django/README.txt +3 -0
- test_holado/tools/django/api_grpc/api_grpc/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/admin.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/apps.py +6 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/migrations/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/models.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account.proto +27 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2.py +33 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2_grpc.py +199 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/serializers.py +12 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/services.py +11 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/tests.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/views.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/asgi.py +16 -0
- test_holado/tools/django/api_grpc/api_grpc/settings.py +126 -0
- test_holado/tools/django/api_grpc/api_grpc/urls.py +27 -0
- test_holado/tools/django/api_grpc/api_grpc/wsgi.py +16 -0
- test_holado/tools/django/api_grpc/db.sqlite3 +0 -0
- test_holado/tools/django/api_grpc/manage.py +29 -0
- test_holado/tools/django/api_grpc/manual_test_commands.txt +25 -0
- test_holado/tools/django/api_grpc/patch_djangogrpcframework.py +42 -0
- test_holado/tools/django/api_rest/api_rest/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/admin.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/apps.py +6 -0
- test_holado/tools/django/api_rest/api_rest/api1/migrations/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/models.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/serializers.py +15 -0
- test_holado/tools/django/api_rest/api_rest/api1/tests.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/views.py +24 -0
- test_holado/tools/django/api_rest/api_rest/asgi.py +16 -0
- test_holado/tools/django/api_rest/api_rest/settings.py +133 -0
- test_holado/tools/django/api_rest/api_rest/urls.py +32 -0
- test_holado/tools/django/api_rest/api_rest/wsgi.py +16 -0
- test_holado/tools/django/api_rest/db.sqlite3 +0 -0
- test_holado/tools/django/api_rest/manage.py +22 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
#################################################
|
|
4
|
+
# HolAdo (Holistic Automation do)
|
|
5
|
+
#
|
|
6
|
+
# (C) Copyright 2021-2025 by Eric Klumpp
|
|
7
|
+
#
|
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
11
|
+
|
|
12
|
+
# The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
|
|
13
|
+
#################################################
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from holado.common.context.session_context import SessionContext
|
|
17
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
18
|
+
from holado_scripting.text.interpreter.text_interpreter import TextInterpreter
|
|
19
|
+
from holado_scripting.common.tools.variable_manager import VariableManager
|
|
20
|
+
from holado_test.common.context.scenario_context import ScenarioContext
|
|
21
|
+
import logging
|
|
22
|
+
from holado_db.tools.db.clients.postgresql.postgresql_client import PostgreSQLClient
|
|
23
|
+
from holado_test.behave.scenario.behave_step_tools import BehaveStepTools
|
|
24
|
+
from holado_value.common.tables.converters.value_table_converter import ValueTableConverter
|
|
25
|
+
from holado_test.scenario.step_tools import StepTools
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def __get_session_context() -> SessionContext:
|
|
32
|
+
return SessionContext.instance()
|
|
33
|
+
|
|
34
|
+
def __get_scenario_context() -> ScenarioContext:
|
|
35
|
+
return __get_session_context().get_scenario_context()
|
|
36
|
+
|
|
37
|
+
def __get_text_interpreter() -> TextInterpreter:
|
|
38
|
+
return __get_scenario_context().get_text_interpreter()
|
|
39
|
+
|
|
40
|
+
def __get_variable_manager() -> VariableManager:
|
|
41
|
+
return __get_scenario_context().get_variable_manager()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if PostgreSQLClient.is_available():
|
|
46
|
+
|
|
47
|
+
@Given(r"(?P<var_name>{Variable}) = new PostreSQL client")
|
|
48
|
+
def step_impl(context, var_name):
|
|
49
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
50
|
+
table = BehaveStepTools.convert_step_table_2_value_table_with_header(context.table)
|
|
51
|
+
kwargs = ValueTableConverter.convert_name_value_table_2_dict(table)
|
|
52
|
+
|
|
53
|
+
client = __get_session_context().db_manager.new_client("postgresql", "postgresql", kwargs)
|
|
54
|
+
client.connect()
|
|
55
|
+
|
|
56
|
+
__get_variable_manager().register_variable(var_name, client)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
#################################################
|
|
4
|
+
# HolAdo (Holistic Automation do)
|
|
5
|
+
#
|
|
6
|
+
# (C) Copyright 2021-2025 by Eric Klumpp
|
|
7
|
+
#
|
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
11
|
+
|
|
12
|
+
# The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
|
|
13
|
+
#################################################
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from holado.common.context.session_context import SessionContext
|
|
17
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
18
|
+
from holado_scripting.text.interpreter.text_interpreter import TextInterpreter
|
|
19
|
+
from holado_scripting.common.tools.variable_manager import VariableManager
|
|
20
|
+
from holado_test.common.context.scenario_context import ScenarioContext
|
|
21
|
+
import logging
|
|
22
|
+
from holado_db.tools.db.clients.sqlite.sqlite_client import SQLite3Client
|
|
23
|
+
from holado_test.behave.scenario.behave_step_tools import BehaveStepTools
|
|
24
|
+
from holado_value.common.tables.converters.value_table_converter import ValueTableConverter
|
|
25
|
+
from holado_test.scenario.step_tools import StepTools
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def __get_session_context() -> SessionContext:
|
|
32
|
+
return SessionContext.instance()
|
|
33
|
+
|
|
34
|
+
def __get_scenario_context() -> ScenarioContext:
|
|
35
|
+
return __get_session_context().get_scenario_context()
|
|
36
|
+
|
|
37
|
+
def __get_text_interpreter() -> TextInterpreter:
|
|
38
|
+
return __get_scenario_context().get_text_interpreter()
|
|
39
|
+
|
|
40
|
+
def __get_variable_manager() -> VariableManager:
|
|
41
|
+
return __get_scenario_context().get_variable_manager()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if SQLite3Client.is_available():
|
|
46
|
+
|
|
47
|
+
@Given(r"(?P<var_name>{Variable}) = new SQLite3 client")
|
|
48
|
+
def step_impl(context, var_name):
|
|
49
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
50
|
+
table = BehaveStepTools.convert_step_table_2_value_table_with_header(context.table)
|
|
51
|
+
kwargs = ValueTableConverter.convert_name_value_table_2_dict(table)
|
|
52
|
+
|
|
53
|
+
client = __get_session_context().db_manager.new_client("sqlite3", "sqlite3", kwargs)
|
|
54
|
+
client.connect()
|
|
55
|
+
|
|
56
|
+
__get_variable_manager().register_variable(var_name, client)
|
|
57
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
|
|
2
|
+
#################################################
|
|
3
|
+
# HolAdo (Holistic Automation do)
|
|
4
|
+
#
|
|
5
|
+
# (C) Copyright 2023 by Eric Klumpp
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
+
#
|
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
+
|
|
11
|
+
# The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
|
|
12
|
+
#################################################
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from holado.common.handlers.object import Object
|
|
16
|
+
import abc
|
|
17
|
+
from holado.common.handlers.undefined import default_value, any_value
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DBAuditManager(Object):
|
|
23
|
+
"""Base class for audit managers.
|
|
24
|
+
"""
|
|
25
|
+
__metaclass__ = abc.ABCMeta
|
|
26
|
+
|
|
27
|
+
def __init__(self, name, db_client):
|
|
28
|
+
super().__init__(name)
|
|
29
|
+
|
|
30
|
+
self.__db_client = db_client
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def _db_client(self):
|
|
34
|
+
return self.__db_client
|
|
35
|
+
|
|
36
|
+
def audit_table(self, table_name, operation_types=any_value, **kwargs):
|
|
37
|
+
raise NotImplementedError()
|
|
38
|
+
|
|
39
|
+
def _get_audit_table_name(self, audit_table_name=default_value):
|
|
40
|
+
if audit_table_name is default_value:
|
|
41
|
+
return "_audit"
|
|
42
|
+
else:
|
|
43
|
+
return audit_table_name
|
|
44
|
+
|
|
45
|
+
def _get_audit_table_sql_create(self, audit_table_name=default_value):
|
|
46
|
+
raise NotImplementedError()
|
|
47
|
+
|
|
48
|
+
def ensure_audit_table_exists(self, audit_table_name=default_value):
|
|
49
|
+
audit_table_name = self._get_audit_table_name(audit_table_name)
|
|
50
|
+
create_sql = self._get_audit_table_sql_create(audit_table_name=audit_table_name)
|
|
51
|
+
self._db_client.create_table(audit_table_name, create_sql, raise_if_exist=False, do_commit=True, do_audit=False)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class TriggerAuditManager(DBAuditManager):
|
|
56
|
+
def __init__(self, name, db_client):
|
|
57
|
+
super().__init__(name, db_client)
|
|
58
|
+
|
|
59
|
+
def audit_table(self, table_name, operation_types=any_value, audit_table_name=default_value, **kwargs):
|
|
60
|
+
self.ensure_audit_table_exists(audit_table_name)
|
|
61
|
+
|
|
62
|
+
if operation_types is any_value:
|
|
63
|
+
operation_types = ['insert', 'update', 'delete']
|
|
64
|
+
else:
|
|
65
|
+
operation_types = [ot.lower() for ot in operation_types]
|
|
66
|
+
|
|
67
|
+
for op_type in operation_types:
|
|
68
|
+
self.drop_trigger_of_audit_table_operation(table_name, op_type, audit_table_name, **kwargs)
|
|
69
|
+
self.create_trigger_to_audit_table_operation(table_name, op_type, audit_table_name, **kwargs)
|
|
70
|
+
|
|
71
|
+
def get_trigger_name(self, table_name, operation_type):
|
|
72
|
+
return f"audit_{table_name}_on_{operation_type}"
|
|
73
|
+
|
|
74
|
+
def drop_trigger_of_audit_table_operation(self, table_name, operation_type, audit_table_name, **kwargs):
|
|
75
|
+
drop_sql = self._get_drop_trigger_sql_of_audit_table_operation(table_name, operation_type, audit_table_name)
|
|
76
|
+
|
|
77
|
+
do_commit = kwargs.pop('do_commit', True)
|
|
78
|
+
self._db_client.execute(drop_sql, do_commit=do_commit, **kwargs)
|
|
79
|
+
|
|
80
|
+
def _get_drop_trigger_sql_of_audit_table_operation(self, table_name, operation_type):
|
|
81
|
+
raise NotImplementedError()
|
|
82
|
+
|
|
83
|
+
def create_trigger_to_audit_table_operation(self, table_name, operation_type, audit_table_name, **kwargs):
|
|
84
|
+
create_sql = self._get_create_trigger_sql_to_audit_table_operation(table_name, operation_type, audit_table_name)
|
|
85
|
+
|
|
86
|
+
do_commit = kwargs.pop('do_commit', True)
|
|
87
|
+
self._db_client.execute(create_sql, do_commit=do_commit, **kwargs)
|
|
88
|
+
|
|
89
|
+
def _get_create_trigger_sql_to_audit_table_operation(self, table_name, operation_type):
|
|
90
|
+
raise NotImplementedError()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
|
|
2
|
+
#################################################
|
|
3
|
+
# HolAdo (Holistic Automation do)
|
|
4
|
+
#
|
|
5
|
+
# (C) Copyright 2023 by Eric Klumpp
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
+
#
|
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
+
|
|
11
|
+
# The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
|
|
12
|
+
#################################################
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from builtins import NotImplementedError
|
|
16
|
+
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
17
|
+
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
18
|
+
from holado_core.common.tables.table_with_header import TableWithHeader
|
|
19
|
+
from holado_core.common.tables.table_row import TableRow
|
|
20
|
+
import abc
|
|
21
|
+
from holado_core.common.tools.tools import Tools
|
|
22
|
+
from holado_core.common.tables.table import Table
|
|
23
|
+
from holado_db.tools.db.query.base.query_builder import QueryBuilder
|
|
24
|
+
from holado_data.data.generator.base import BaseGenerator
|
|
25
|
+
from holado_python.standard_library.typing import Typing
|
|
26
|
+
from holado.common.handlers.object import Object
|
|
27
|
+
|
|
28
|
+
logger = logging.getLogger(__name__)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class DBClient(Object):
|
|
32
|
+
__metaclass__ = abc.ABCMeta
|
|
33
|
+
|
|
34
|
+
def __init__(self, name, connect_kwargs, with_cursor=True, auto_commit=True):
|
|
35
|
+
super().__init__(name)
|
|
36
|
+
|
|
37
|
+
self.__connect_kwargs = connect_kwargs
|
|
38
|
+
self.__with_cursor = with_cursor
|
|
39
|
+
self.__auto_commit = auto_commit
|
|
40
|
+
|
|
41
|
+
self.__connection = None
|
|
42
|
+
self.__query_builder = None
|
|
43
|
+
self.__audit_manager = None
|
|
44
|
+
self.__column_names_by_table = {}
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def query_builder(self) -> QueryBuilder:
|
|
48
|
+
return self.__query_builder
|
|
49
|
+
|
|
50
|
+
@query_builder.setter
|
|
51
|
+
def query_builder(self, builder):
|
|
52
|
+
self.__query_builder = builder
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def is_connected(self):
|
|
56
|
+
return self.__connection is not None
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def connection(self):
|
|
60
|
+
return self.__connection
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def cursor(self):
|
|
64
|
+
if not self.__with_cursor:
|
|
65
|
+
raise TechnicalException(f"DB client '{self.__name}' doesn't manage cursor")
|
|
66
|
+
return self.__cursor
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def audit_manager(self):
|
|
70
|
+
if self.__audit_manager is None:
|
|
71
|
+
self.__audit_manager = self._new_audit_manager()
|
|
72
|
+
return self.__audit_manager
|
|
73
|
+
|
|
74
|
+
def _new_audit_manager(self):
|
|
75
|
+
"""Create a new audit manager.
|
|
76
|
+
By default, use a audit manager with a single table of audit for whole DB and with triggers on audited tables.
|
|
77
|
+
Override this method in order to define which audit manager to use.
|
|
78
|
+
"""
|
|
79
|
+
raise NotImplementedError()
|
|
80
|
+
|
|
81
|
+
def connect(self):
|
|
82
|
+
try:
|
|
83
|
+
self.__connection = self._connect(**self.__connect_kwargs)
|
|
84
|
+
except Exception as exc:
|
|
85
|
+
Tools.raise_same_exception_type(exc, f"[{self.name}] Failed to connect with parameters {self.__connect_kwargs}")
|
|
86
|
+
if self.__with_cursor:
|
|
87
|
+
self.__cursor = self.__connection.cursor()
|
|
88
|
+
|
|
89
|
+
def _connect(self, **kwargs):
|
|
90
|
+
raise NotImplementedError()
|
|
91
|
+
|
|
92
|
+
def _verify_is_connected(self):
|
|
93
|
+
if not self.is_connected:
|
|
94
|
+
raise FunctionalException(f"DB Client '{self.name}' is not connected")
|
|
95
|
+
|
|
96
|
+
# Manage queries
|
|
97
|
+
|
|
98
|
+
def insert(self, table_name, data: dict, do_commit=None):
|
|
99
|
+
"""
|
|
100
|
+
Insert given data.
|
|
101
|
+
Parameter 'data' has to be a dictionary with keys equal to table column names.
|
|
102
|
+
"""
|
|
103
|
+
query, values = self.query_builder.insert(table_name, data)
|
|
104
|
+
return self.execute_query(query, *values, do_commit=do_commit)
|
|
105
|
+
|
|
106
|
+
def update(self, table_name, data: dict, where_data: dict=None, where_compare_data: list=None, do_commit=None):
|
|
107
|
+
"""
|
|
108
|
+
Update given data.
|
|
109
|
+
Parameters 'data' and 'where_data' have to be dictionaries with keys equal to table column names.
|
|
110
|
+
"""
|
|
111
|
+
query, values = self.query_builder.update(table_name, data, where_data=where_data, where_compare_data=where_compare_data)
|
|
112
|
+
return self.execute_query(query, *values, do_commit=do_commit)
|
|
113
|
+
|
|
114
|
+
def select(self, table_name, where_data: dict=None, where_compare_data: list=None, sql_return="*", **kwargs):
|
|
115
|
+
"""
|
|
116
|
+
Select by filtering on given where data.
|
|
117
|
+
@param where_data: dictionary of (field_name, value) for simple where clauses.
|
|
118
|
+
@param where_compare_data: list of tuples (field_name, operator, value) for where clauses comparing fields with values.
|
|
119
|
+
"""
|
|
120
|
+
query, values = self.query_builder.select(table_name, where_data=where_data, where_compare_data=where_compare_data, sql_return=sql_return)
|
|
121
|
+
return self.execute_query(query, *values, do_commit=False, **kwargs)
|
|
122
|
+
|
|
123
|
+
def delete(self, table_name, where_data: dict=None, where_compare_data: list=None, do_commit=None):
|
|
124
|
+
"""
|
|
125
|
+
Delete by filtering on given where data.
|
|
126
|
+
Parameter 'where_data' has to be a dictionary with keys equal to table column names.
|
|
127
|
+
"""
|
|
128
|
+
query, values = self.query_builder.delete(table_name, where_data=where_data, where_compare_data=where_compare_data)
|
|
129
|
+
return self.execute_query(query, *values, do_commit=do_commit)
|
|
130
|
+
|
|
131
|
+
def count(self, table_name, where_data: dict=None, where_compare_data: list=None):
|
|
132
|
+
result = self.select(table_name, where_data=where_data, where_compare_data=where_compare_data, sql_return="count(*)")
|
|
133
|
+
return result[0][0].content
|
|
134
|
+
|
|
135
|
+
def execute_query(self, query, *args, **kwargs):
|
|
136
|
+
sql = self.query_builder.to_sql(query)
|
|
137
|
+
|
|
138
|
+
# Force do_commit to False for select queries
|
|
139
|
+
do_commit = kwargs.pop('do_commit', None)
|
|
140
|
+
|
|
141
|
+
return self.execute(sql, *args, do_commit=do_commit, **kwargs)
|
|
142
|
+
|
|
143
|
+
def execute(self, sql, *args, **kwargs):
|
|
144
|
+
# Manage specific parameters
|
|
145
|
+
if self.is_query_type(sql, 'select'):
|
|
146
|
+
do_commit = False
|
|
147
|
+
else:
|
|
148
|
+
do_commit = kwargs.pop('do_commit', None)
|
|
149
|
+
if do_commit is None:
|
|
150
|
+
do_commit = self.__auto_commit
|
|
151
|
+
result_as_dict_list = kwargs.pop('result_as_dict_list', False)
|
|
152
|
+
as_generator = kwargs.pop('as_generator', False)
|
|
153
|
+
if as_generator and do_commit:
|
|
154
|
+
raise TechnicalException(f"'do_commit=True' and 'as_generator=True' are incompatible")
|
|
155
|
+
if as_generator and not result_as_dict_list:
|
|
156
|
+
raise TechnicalException(f"'as_generator=True' is possible only with 'result_as_dict_list=True'")
|
|
157
|
+
|
|
158
|
+
self._verify_is_connected()
|
|
159
|
+
|
|
160
|
+
# Execute
|
|
161
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
162
|
+
logger.debug(f"[{self.name}] Executing SQL [{Tools.truncate_text(sql, 1000)}] (args: {Tools.truncate_text(args, 1000)} ; kwargs: {Tools.truncate_text(kwargs, 1000)})...")
|
|
163
|
+
try:
|
|
164
|
+
if args:
|
|
165
|
+
self.cursor.execute(sql, args)
|
|
166
|
+
elif kwargs:
|
|
167
|
+
self.cursor.execute(sql, kwargs)
|
|
168
|
+
else:
|
|
169
|
+
self.cursor.execute(sql)
|
|
170
|
+
except self._get_base_exception_type() as exc:
|
|
171
|
+
self.rollback()
|
|
172
|
+
raise TechnicalException(f"[{self.name}] Error while executing SQL [{sql}] (args: {args} ; kwargs: {kwargs})") from exc
|
|
173
|
+
|
|
174
|
+
# Get result
|
|
175
|
+
if self.cursor.description:
|
|
176
|
+
field_names = [field[0] for field in self.cursor.description]
|
|
177
|
+
|
|
178
|
+
if result_as_dict_list:
|
|
179
|
+
class Cursor2DictGenerator(BaseGenerator):
|
|
180
|
+
def __init__(self, field_names, cursor):
|
|
181
|
+
super().__init__(name="DB cursor to dict generator")
|
|
182
|
+
self.__field_names = field_names
|
|
183
|
+
self.__cursor = cursor
|
|
184
|
+
self.__cursor_iter = iter(self.__cursor)
|
|
185
|
+
|
|
186
|
+
def __next__(self):
|
|
187
|
+
row_values = next(self.__cursor_iter)
|
|
188
|
+
return dict(zip(self.__field_names, row_values))
|
|
189
|
+
|
|
190
|
+
gen = Cursor2DictGenerator(field_names, self.cursor)
|
|
191
|
+
if as_generator:
|
|
192
|
+
res = gen
|
|
193
|
+
else:
|
|
194
|
+
res = [e for e in gen]
|
|
195
|
+
else:
|
|
196
|
+
res = TableWithHeader()
|
|
197
|
+
res.header = TableRow(cells_content=field_names)
|
|
198
|
+
|
|
199
|
+
row_values = self.cursor.fetchone()
|
|
200
|
+
while row_values:
|
|
201
|
+
res.add_row(cells_content=row_values)
|
|
202
|
+
row_values = self.cursor.fetchone()
|
|
203
|
+
elif self.cursor.rowcount > 0:
|
|
204
|
+
res = self.cursor.rowcount
|
|
205
|
+
else:
|
|
206
|
+
res = None
|
|
207
|
+
|
|
208
|
+
self.__log_sql_result(res, message=f"Executed SQL [{Tools.truncate_text(sql, 1000)}] (args: {Tools.truncate_text(args, 1000)} ; kwargs: {Tools.truncate_text(kwargs, 1000)})")
|
|
209
|
+
|
|
210
|
+
# Manage commit
|
|
211
|
+
if do_commit:
|
|
212
|
+
try:
|
|
213
|
+
self.commit()
|
|
214
|
+
except self._get_base_exception_type() as exc:
|
|
215
|
+
self.rollback()
|
|
216
|
+
raise TechnicalException(f"[{self.name}] Error while commit after SQL [{sql}] (args: {args} ; kwargs: {kwargs})") from exc
|
|
217
|
+
|
|
218
|
+
return res
|
|
219
|
+
|
|
220
|
+
def is_query_type(self, sql_or_query, query_type):
|
|
221
|
+
from sql_metadata.keywords_lists import QueryType
|
|
222
|
+
import sql_metadata
|
|
223
|
+
import pypika.queries
|
|
224
|
+
|
|
225
|
+
if isinstance(sql_or_query, pypika.queries.QueryBuilder):
|
|
226
|
+
sql = self.query_builder.to_sql(sql_or_query)
|
|
227
|
+
else:
|
|
228
|
+
sql = sql_or_query
|
|
229
|
+
if not isinstance(sql, str):
|
|
230
|
+
raise TechnicalException(f"Unexpected type '{Typing.get_object_class_fullname(sql)}' for parameter sql_or_query")
|
|
231
|
+
sql = sql.lower()
|
|
232
|
+
|
|
233
|
+
# Parsing query with sql_metadata can be costly, thus begin by fast and simple methods
|
|
234
|
+
query_type_str = query_type.lower() if isinstance(query_type, str) else query_type.name.lower()
|
|
235
|
+
for qt in ['select', 'insert', 'update', 'delete']:
|
|
236
|
+
if sql.startswith(qt):
|
|
237
|
+
return qt == query_type_str
|
|
238
|
+
|
|
239
|
+
# Parse more complex queries
|
|
240
|
+
if isinstance(query_type, str):
|
|
241
|
+
query_type = QueryType[query_type.upper()]
|
|
242
|
+
if not isinstance(query_type, QueryType):
|
|
243
|
+
raise TechnicalException(f"Unmanage query_type of type '{Typing.get_object_class_fullname(query_type)}'")
|
|
244
|
+
|
|
245
|
+
try:
|
|
246
|
+
p = sql_metadata.Parser(sql)
|
|
247
|
+
res = p.query_type == query_type
|
|
248
|
+
except ValueError as exc:
|
|
249
|
+
if "Not supported query type" in str(exc):
|
|
250
|
+
res = False
|
|
251
|
+
else:
|
|
252
|
+
raise TechnicalException(f"Failed to define query type") from exc
|
|
253
|
+
except Exception as exc:
|
|
254
|
+
raise TechnicalException(f"Failed to define query type") from exc
|
|
255
|
+
|
|
256
|
+
return res
|
|
257
|
+
|
|
258
|
+
def set_or_update_json_key_value(self, table_name, field_name, json_key, json_value, where_data: dict=None, where_compare_data: list=None):
|
|
259
|
+
"""
|
|
260
|
+
Set or update a json field with key=value.
|
|
261
|
+
"""
|
|
262
|
+
raise NotImplementedError()
|
|
263
|
+
|
|
264
|
+
def _get_sql_placeholder(self):
|
|
265
|
+
"""
|
|
266
|
+
Return the character/string to use as placeholder in SQL requests.
|
|
267
|
+
"""
|
|
268
|
+
raise NotImplementedError()
|
|
269
|
+
|
|
270
|
+
def _get_base_exception_type(self):
|
|
271
|
+
raise NotImplementedError()
|
|
272
|
+
|
|
273
|
+
def __log_sql_result(self, sql_result, message="SQL result", limit_rows=10):
|
|
274
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
275
|
+
res_str = self.__represent_sql_result(sql_result, limit_rows=limit_rows)
|
|
276
|
+
if '\n' in res_str:
|
|
277
|
+
logger.debug(f"[{self.name}] {message}:\n{Tools.indent_string(4, res_str)}")
|
|
278
|
+
else:
|
|
279
|
+
logger.debug(f"[{self.name}] {message} => {res_str}")
|
|
280
|
+
|
|
281
|
+
def __represent_sql_result(self, sql_result, limit_rows = 10):
|
|
282
|
+
if isinstance(sql_result, Table):
|
|
283
|
+
return sql_result.represent(limit_rows=limit_rows)
|
|
284
|
+
elif isinstance(sql_result, list) and limit_rows > 0 and len(sql_result) > limit_rows:
|
|
285
|
+
return str(sql_result[:limit_rows])[:-1] + f", ...({len(sql_result)-limit_rows})]"
|
|
286
|
+
else:
|
|
287
|
+
return str(sql_result)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
# Manage transactions
|
|
291
|
+
|
|
292
|
+
def commit(self):
|
|
293
|
+
self.connection.commit()
|
|
294
|
+
|
|
295
|
+
def rollback(self):
|
|
296
|
+
self.connection.rollback()
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
# Manage tables
|
|
300
|
+
|
|
301
|
+
def exist_table(self, table_name):
|
|
302
|
+
raise NotImplementedError()
|
|
303
|
+
|
|
304
|
+
def create_table(self, table_name, create_sql, raise_if_exist=False, do_commit=True, do_audit=False):
|
|
305
|
+
if not self.exist_table(table_name):
|
|
306
|
+
self.execute(create_sql, do_commit=do_commit)
|
|
307
|
+
if not self.exist_table(table_name):
|
|
308
|
+
raise TechnicalException(f"Failed to create table '{table_name}' with SQL request [{create_sql}]")
|
|
309
|
+
|
|
310
|
+
# Audit table
|
|
311
|
+
if do_audit:
|
|
312
|
+
self.audit_manager.audit_table(table_name)
|
|
313
|
+
elif raise_if_exist:
|
|
314
|
+
raise FunctionalException(f"Table '{table_name}' already exists")
|
|
315
|
+
|
|
316
|
+
def drop_table(self, table_name, raise_if_not_exist=False, do_commit=True):
|
|
317
|
+
if self.exist_table(table_name):
|
|
318
|
+
sql = f"drop table {table_name};"
|
|
319
|
+
self.execute(sql, do_commit=do_commit)
|
|
320
|
+
if self.exist_table(table_name):
|
|
321
|
+
raise TechnicalException(f"Failed to drop table '{table_name}' with SQL request [{sql}]")
|
|
322
|
+
elif raise_if_not_exist:
|
|
323
|
+
raise FunctionalException(f"Table '{table_name}' doesn't exist")
|
|
324
|
+
|
|
325
|
+
def get_table_column_names(self, table_name):
|
|
326
|
+
if table_name not in self.__column_names_by_table:
|
|
327
|
+
self.__column_names_by_table[table_name] = self._get_table_column_names(table_name)
|
|
328
|
+
return self.__column_names_by_table[table_name]
|
|
329
|
+
|
|
330
|
+
def _get_table_column_names(self, table_name):
|
|
331
|
+
sql = f"select * from {table_name} limit 1"
|
|
332
|
+
try:
|
|
333
|
+
self.cursor.execute(sql)
|
|
334
|
+
except self._get_base_exception_type() as exc:
|
|
335
|
+
self.rollback()
|
|
336
|
+
raise TechnicalException(f"[{self.name}] Error while executing SQL [{sql}]") from exc
|
|
337
|
+
|
|
338
|
+
if self.cursor.description:
|
|
339
|
+
res = [field[0] for field in self.cursor.description]
|
|
340
|
+
else:
|
|
341
|
+
raise TechnicalException(f"Failed to get column names of table {table_name}")
|
|
342
|
+
|
|
343
|
+
return res
|
|
344
|
+
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
|
|
2
|
+
#################################################
|
|
3
|
+
# HolAdo (Holistic Automation do)
|
|
4
|
+
#
|
|
5
|
+
# (C) Copyright 2023 by Eric Klumpp
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
+
#
|
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
+
|
|
11
|
+
# The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
|
|
12
|
+
#################################################
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from holado.common.handlers.undefined import default_value
|
|
16
|
+
from holado_db.tools.db.clients.base.db_audit import TriggerAuditManager
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PostgreSQLTriggerAuditManager(TriggerAuditManager):
|
|
22
|
+
"""Manage audit of tables by triggers.
|
|
23
|
+
WARNING: This case is not tested yet
|
|
24
|
+
"""
|
|
25
|
+
def __init__(self, name, db_client):
|
|
26
|
+
super().__init__(name, db_client)
|
|
27
|
+
|
|
28
|
+
def _get_audit_table_sql_create(self, audit_table_name=default_value):
|
|
29
|
+
audit_table_name = self._get_audit_table_name(audit_table_name)
|
|
30
|
+
return f"""CREATE TABLE {audit_table_name} (
|
|
31
|
+
id SERIAL PRIMARY KEY,
|
|
32
|
+
table_name TEXT,
|
|
33
|
+
record_id INTEGER,
|
|
34
|
+
operation_type TEXT,
|
|
35
|
+
changed_at TIMESTAMP DEFAULT now(),
|
|
36
|
+
changed_by TEXT,
|
|
37
|
+
previous_values JSONB,
|
|
38
|
+
new_values JSONB
|
|
39
|
+
)"""
|
|
40
|
+
|
|
41
|
+
def _get_drop_trigger_sql_of_audit_table_operation(self, table_name, operation_type, audit_table_name):
|
|
42
|
+
audit_table_name = self._get_audit_table_name(audit_table_name)
|
|
43
|
+
trigger_name = self.get_trigger_name(table_name, operation_type)
|
|
44
|
+
return f"DROP TRIGGER IF EXISTS {trigger_name} on {table_name}"
|
|
45
|
+
|
|
46
|
+
def _get_create_trigger_sql_to_audit_table_operation(self, table_name, operation_type, audit_table_name):
|
|
47
|
+
audit_table_name = self._get_audit_table_name(audit_table_name)
|
|
48
|
+
trigger_name = self.get_trigger_name(table_name, operation_type)
|
|
49
|
+
trigger_insert_sql = self.__get_trigger_insert_sql(table_name, operation_type, audit_table_name)
|
|
50
|
+
return f"""CREATE TRIGGER {trigger_name} AFTER {operation_type.upper()} ON {table_name}
|
|
51
|
+
BEGIN
|
|
52
|
+
{trigger_insert_sql}
|
|
53
|
+
END;
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __get_trigger_insert_sql(self, table_name, operation_type, audit_table_name):
|
|
57
|
+
rowid_txt = "NEW.id" if operation_type in ['insert', 'update'] else "OLD.id"
|
|
58
|
+
op_type = operation_type[0]
|
|
59
|
+
prev_vals_txt = "to_jsonb(OLD)" if operation_type in ['update', 'delete'] else "NULL"
|
|
60
|
+
new_vals_txt = "to_jsonb(NEW)" if operation_type in ['insert', 'update'] else "NULL"
|
|
61
|
+
|
|
62
|
+
audit_info = [f"'{table_name}'",
|
|
63
|
+
rowid_txt,
|
|
64
|
+
f"'{op_type}'",
|
|
65
|
+
"current_user",
|
|
66
|
+
prev_vals_txt,
|
|
67
|
+
new_vals_txt,
|
|
68
|
+
]
|
|
69
|
+
audit_info = ','.join(audit_info)
|
|
70
|
+
|
|
71
|
+
return f"""INSERT INTO {audit_table_name} (table_name, record_id, operation_type, changed_by, previous_values, new_values)
|
|
72
|
+
VALUES ({audit_info});"""
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|