mycli 2.28.0__tar.gz → 2.28.1__tar.gz
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.
- mycli-2.28.1/.git-blame-ignore-revs +43 -0
- {mycli-2.28.0 → mycli-2.28.1}/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- {mycli-2.28.0 → mycli-2.28.1}/.github/workflows/ci.yml +3 -3
- {mycli-2.28.0 → mycli-2.28.1}/.github/workflows/lint.yml +3 -3
- {mycli-2.28.0 → mycli-2.28.1}/.github/workflows/typecheck.yml +3 -3
- mycli-2.28.1/AGENTS.md +149 -0
- mycli-2.28.1/AUTHORS.md +1 -0
- {mycli-2.28.0 → mycli-2.28.1}/CONTRIBUTING.md +1 -1
- mycli-2.28.1/MANIFEST.in +6 -0
- {mycli-2.28.0/mycli.egg-info → mycli-2.28.1}/PKG-INFO +2 -1
- mycli-2.28.1/SPONSORS.md +1 -0
- {mycli-2.28.0 → mycli-2.28.1}/changelog.md +31 -0
- {mycli-2.28.0 → mycli-2.28.1}/docker/resources/test_db-1.0.7.tar.gz +1 -1
- {mycli-2.28.0 → mycli-2.28.1}/mycli/cli_runner.py +8 -8
- {mycli-2.28.0 → mycli-2.28.1}/mycli/client.py +22 -22
- {mycli-2.28.0 → mycli-2.28.1}/mycli/client_commands.py +28 -28
- {mycli-2.28.0 → mycli-2.28.1}/mycli/client_connection.py +16 -16
- {mycli-2.28.0 → mycli-2.28.1}/mycli/client_query.py +15 -15
- {mycli-2.28.0 → mycli-2.28.1}/mycli/main.py +4 -4
- {mycli-2.28.0 → mycli-2.28.1}/mycli/main_modes/batch.py +3 -3
- {mycli-2.28.0 → mycli-2.28.1}/mycli/main_modes/execute.py +2 -2
- {mycli-2.28.0 → mycli-2.28.1}/mycli/main_modes/list_dsn.py +1 -1
- {mycli-2.28.0 → mycli-2.28.1}/mycli/main_modes/repl.py +118 -118
- {mycli-2.28.0 → mycli-2.28.1}/mycli/output.py +20 -20
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/completion}/completion_engine.py +6 -6
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/completion}/completion_refresher.py +7 -7
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/completion}/schema_prefetcher.py +16 -16
- mycli-2.28.0/mycli/sqlcompleter.py → mycli-2.28.1/mycli/packages/completion/sql_completer.py +9 -9
- mycli-2.28.0/mycli/packages/polars_completion.py → mycli-2.28.1/mycli/packages/dataframes/completion.py +2 -2
- mycli-2.28.0/mycli/packages/polars_transform.py → mycli-2.28.1/mycli/packages/dataframes/transform.py +8 -3
- mycli-2.28.0/mycli/query_runner.py → mycli-2.28.1/mycli/packages/execution/background_runner.py +7 -7
- mycli-2.28.0/mycli/sqlexecute.py → mycli-2.28.1/mycli/packages/execution/sql_execute.py +17 -17
- mycli-2.28.1/mycli/packages/integrations/boundary/__init__.py +0 -0
- mycli-2.28.1/mycli/packages/integrations/fzf/__init__.py +0 -0
- mycli-2.28.1/mycli/packages/integrations/kubernetes/__init__.py +0 -0
- mycli-2.28.1/mycli/packages/integrations/macos/__init__.py +0 -0
- mycli-2.28.1/mycli/packages/integrations/openssh/__init__.py +0 -0
- mycli-2.28.1/mycli/packages/integrations/vault/__init__.py +0 -0
- mycli-2.28.1/mycli/packages/prompt_toolkit/__init__.py +0 -0
- {mycli-2.28.0/mycli/packages/ptoolkit → mycli-2.28.1/mycli/packages/prompt_toolkit}/fzf_history.py +3 -3
- {mycli-2.28.0/mycli/packages/ptoolkit → mycli-2.28.1/mycli/packages/prompt_toolkit}/history.py +1 -1
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/prompt_toolkit}/key_bindings.py +9 -9
- mycli-2.28.0/mycli/clibuffer.py → mycli-2.28.1/mycli/packages/prompt_toolkit/multiline.py +5 -5
- mycli-2.28.0/mycli/clistyle.py → mycli-2.28.1/mycli/packages/prompt_toolkit/style.py +6 -6
- mycli-2.28.0/mycli/clitoolbar.py → mycli-2.28.1/mycli/packages/prompt_toolkit/toolbar.py +2 -2
- mycli-2.28.1/mycli/packages/pygments/__init__.py +0 -0
- mycli-2.28.1/mycli/packages/redirection/__init__.py +0 -0
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/redirection}/hybrid_redirection.py +2 -2
- {mycli-2.28.0/mycli/packages/special → mycli-2.28.1/mycli/packages/special_commands}/__init__.py +5 -5
- mycli-2.28.0/mycli/packages/special/dbcommands.py → mycli-2.28.1/mycli/packages/special_commands/db_commands.py +9 -9
- mycli-2.28.0/mycli/packages/special/delimitercommand.py → mycli-2.28.1/mycli/packages/special_commands/delimiter_command.py +1 -1
- {mycli-2.28.0/mycli/packages/special → mycli-2.28.1/mycli/packages/special_commands}/dsn_aliases.py +4 -4
- mycli-2.28.0/mycli/packages/special/iocommands.py → mycli-2.28.1/mycli/packages/special_commands/io_commands.py +12 -12
- {mycli-2.28.0/mycli/packages/special → mycli-2.28.1/mycli/packages/special_commands}/llm.py +2 -2
- {mycli-2.28.0/mycli/packages/special → mycli-2.28.1/mycli/packages/special_commands}/main.py +1 -1
- {mycli-2.28.0/mycli/packages/special → mycli-2.28.1/mycli/packages/special_commands}/source.py +5 -5
- mycli-2.28.1/mycli/packages/sql_result/__init__.py +0 -0
- mycli-2.28.1/mycli/packages/tabular_output/__init__.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/packages/tabular_output/sql_format.py +2 -2
- mycli-2.28.1/mycli/packages/utils/__init__.py +0 -0
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/utils}/interactive_utils.py +1 -1
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/utils}/key_binding_utils.py +13 -13
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/utils}/keyring_utils.py +1 -1
- {mycli-2.28.0 → mycli-2.28.1/mycli.egg-info}/PKG-INFO +2 -1
- mycli-2.28.1/mycli.egg-info/SOURCES.txt +222 -0
- mycli-2.28.1/mycli.egg-info/scm_file_list.json +218 -0
- mycli-2.28.1/mycli.egg-info/scm_version.json +8 -0
- mycli-2.28.1/mycli.egg-info/top_level.txt +2 -0
- mycli-2.28.1/mycli_test/__init__.py +0 -0
- mycli-2.28.1/mycli_test/features/__init__.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/environment.py +8 -8
- mycli-2.28.1/mycli_test/features/steps/__init__.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/basic_commands.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/connection.py +2 -2
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/myclirc +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/conftest.py +3 -3
- mycli-2.28.0/test/pytests/test_query_runner.py → mycli-2.28.1/mycli_test/pytests/test_background_runner.py +133 -133
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_batch_utils.py +5 -5
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_boundary_tunnel.py +2 -2
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_cli_runner.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_cli_utils.py +2 -2
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_clibuffer.py +21 -21
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_client.py +6 -6
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_client_commands.py +66 -66
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_client_connection.py +10 -10
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_client_query.py +19 -19
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_completer_use_switch.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_completion_engine.py +5 -4
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_completion_refresher.py +32 -32
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_config.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_delimitercommand.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_dsn_aliases.py +7 -7
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_favoritequeries.py +13 -13
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_fzf.py +2 -2
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_hybrid_redirection.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_interactive_utils.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_key_binding_utils.py +23 -23
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_key_bindings.py +4 -4
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_keyring_utils.py +2 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_kubectl_tunnel.py +2 -2
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_macos_keychain.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_main.py +53 -57
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_main_modes_batch.py +2 -2
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_main_modes_repl.py +154 -154
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_naive_completion.py +3 -3
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_output.py +67 -67
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_password_sources.py +1 -1
- mycli-2.28.0/test/pytests/test_filepaths.py → mycli-2.28.1/mycli_test/pytests/test_path_utils.py +44 -44
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_polars_completion.py +3 -3
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_polars_transform.py +7 -7
- mycli-2.28.0/test/pytests/test_ptoolkit_fzf_history.py → mycli-2.28.1/mycli_test/pytests/test_prompt_toolkit_fzf_history.py +23 -23
- mycli-2.28.0/test/pytests/test_ptoolkit_history.py → mycli-2.28.1/mycli_test/pytests/test_prompt_toolkit_history.py +2 -2
- mycli-2.28.0/test/pytests/test_clistyle.py → mycli-2.28.1/mycli_test/pytests/test_prompt_toolkit_style.py +30 -30
- mycli-2.28.0/test/pytests/test_clitoolbar.py → mycli-2.28.1/mycli_test/pytests/test_prompt_toolkit_toolbar.py +15 -15
- mycli-2.28.0/test/pytests/test_ptoolkit_utils.py → mycli-2.28.1/mycli_test/pytests/test_prompt_toolkit_utils.py +5 -5
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_schema_prefetcher.py +5 -5
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_smart_completion_public_schema_only.py +35 -35
- mycli-2.28.1/mycli_test/pytests/test_special_commands_init.py +103 -0
- mycli-2.28.0/test/pytests/test_special_dbcommands.py → mycli-2.28.1/mycli_test/pytests/test_special_db_commands.py +25 -25
- mycli-2.28.0/test/pytests/test_special_iocommands.py → mycli-2.28.1/mycli_test/pytests/test_special_io_commands.py +475 -473
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_special_llm.py +27 -27
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_special_main.py +123 -123
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_special_source.py +6 -6
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_special_utils.py +7 -7
- mycli-2.28.0/test/pytests/test_sqlexecute.py → mycli-2.28.1/mycli_test/pytests/test_sql_execute.py +133 -133
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_sql_utils.py +2 -2
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_sqlcompleter.py +59 -59
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_sqlresult.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_ssh_tunnel.py +2 -2
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_string_utils.py +1 -1
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_tabular_output.py +4 -4
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_vault.py +22 -22
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/utils.py +5 -5
- {mycli-2.28.0 → mycli-2.28.1}/pyproject.toml +5 -4
- mycli-2.28.0/.git-blame-ignore-revs +0 -6
- mycli-2.28.0/AGENTS.md +0 -152
- mycli-2.28.0/AUTHORS.md +0 -1
- mycli-2.28.0/MANIFEST.in +0 -6
- mycli-2.28.0/SPONSORS.md +0 -1
- mycli-2.28.0/mycli.egg-info/SOURCES.txt +0 -207
- mycli-2.28.0/mycli.egg-info/scm_file_list.json +0 -203
- mycli-2.28.0/mycli.egg-info/scm_version.json +0 -8
- mycli-2.28.0/mycli.egg-info/top_level.txt +0 -1
- mycli-2.28.0/test/pytests/test_special_init.py +0 -103
- {mycli-2.28.0 → mycli-2.28.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/.github/dependabot.yml +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/.github/workflows/publish.yml +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/.gitignore +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/LICENSE.txt +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/README.md +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/cookbook.md +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/key_bindings.md +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/known_bugs.md +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/llm.md +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/screenshots/main.gif +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/screenshots/polars_describe.png +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/screenshots/polars_group_by.png +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/screenshots/polars_histogram.png +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/screenshots/polars_pivot.png +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/screenshots/tables.png +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/doc/transforms.md +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/docker/Dockerfile +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/docker/resources/test_db_license.md +0 -0
- /mycli-2.28.0/mycli/AUTHORS → /mycli-2.28.1/mycli/AUTHORS.txt +0 -0
- /mycli-2.28.0/mycli/SPONSORS → /mycli-2.28.1/mycli/SPONSORS.txt +0 -0
- /mycli-2.28.0/mycli/TIPS → /mycli-2.28.1/mycli/TIPS.txt +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/__init__.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/app_state.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/compat.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/config.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/constants.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/main_modes/checkup.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/main_modes/completions.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/myclirc +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/packages/__init__.py +0 -0
- {mycli-2.28.0/mycli/packages/ptoolkit → mycli-2.28.1/mycli/packages/completion}/__init__.py +0 -0
- {mycli-2.28.0/mycli/packages/tabular_output → mycli-2.28.1/mycli/packages/credentials}/__init__.py +0 -0
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/credentials}/password_sources.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli/packages/dataframes}/__init__.py +0 -0
- {mycli-2.28.0/test/features → mycli-2.28.1/mycli/packages/execution}/__init__.py +0 -0
- {mycli-2.28.0/test/features/steps → mycli-2.28.1/mycli/packages/integrations}/__init__.py +0 -0
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/integrations/boundary}/boundary_tunnel.py +0 -0
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/integrations/fzf}/fzf.py +0 -0
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/integrations/kubernetes}/kubectl_tunnel.py +0 -0
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/integrations/macos}/macos_keychain.py +0 -0
- {mycli-2.28.0/mycli → mycli-2.28.1/mycli/packages/integrations/openssh}/ssh_tunnel.py +0 -0
- /mycli-2.28.0/mycli/vault.py → /mycli-2.28.1/mycli/packages/integrations/vault/vault_credentials.py +0 -0
- {mycli-2.28.0/mycli/packages/ptoolkit → mycli-2.28.1/mycli/packages/prompt_toolkit}/utils.py +0 -0
- /mycli-2.28.0/mycli/lexer.py → /mycli-2.28.1/mycli/packages/pygments/mycli_lexer.py +0 -0
- /mycli-2.28.0/mycli/packages/special/favoritequeries.py → /mycli-2.28.1/mycli/packages/special_commands/favorite_queries.py +0 -0
- /mycli-2.28.0/mycli/packages/special/utils.py → /mycli-2.28.1/mycli/packages/special_commands/special_command_utils.py +0 -0
- /mycli-2.28.0/mycli/packages/sqlresult.py → /mycli-2.28.1/mycli/packages/sql_result/sql_result.py +0 -0
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/utils}/batch_utils.py +0 -0
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/utils}/cli_utils.py +0 -0
- /mycli-2.28.0/mycli/packages/filepaths.py → /mycli-2.28.1/mycli/packages/utils/path_utils.py +0 -0
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/utils}/sql_utils.py +0 -0
- {mycli-2.28.0/mycli/packages → mycli-2.28.1/mycli/packages/utils}/string_utils.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/resources/completions/bash/mycli +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/resources/completions/fish/mycli.fish +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/resources/completions/zsh/_mycli +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli/types.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli.egg-info/dependency_links.txt +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli.egg-info/entry_points.txt +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/mycli.egg-info/requires.txt +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/auto_vertical.feature +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/basic_commands.feature +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/connection.feature +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/crud_database.feature +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/crud_table.feature +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/db_utils.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/fixture_data/help_commands.txt +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/fixture_utils.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/iocommands.feature +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/named_queries.feature +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/specials.feature +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/auto_vertical.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/crud_database.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/crud_table.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/iocommands.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/named_queries.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/specials.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/utils.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/steps/wrappers.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/features/wrappager.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/mylogin.cnf +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_app_state.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_bash_completion.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_checkup.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_fish_completion.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_main_modes_execute.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_main_modes_list_dsn.py +0 -0
- {mycli-2.28.0/test → mycli-2.28.1/mycli_test}/pytests/test_zsh_completion.py +0 -0
- {mycli-2.28.0 → mycli-2.28.1}/setup.cfg +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# rename "toolkit" to "ptoolkit"
|
|
2
|
+
d891e5ae670c44b96ecd79fca36da91748d8c44a
|
|
3
|
+
4c8b5bfb314ed8998b8652613f0669fe58537a62
|
|
4
|
+
# gather pytest files in a subdirectory
|
|
5
|
+
9dbad2c5be3786eacbb127362b9b37f41b4d4785
|
|
6
|
+
eb4526c66f141734b806d4782968135772f39557
|
|
7
|
+
# refactor moves 2026-10-03
|
|
8
|
+
07df6f36996c7c7c8665ef58dbabf735eff12557
|
|
9
|
+
95e378d136a5fd115469aa3931b551c50f8f93e1
|
|
10
|
+
25951150261aa6d64d4ea2efc4aad77a25b39e83
|
|
11
|
+
b7dc69e6aa254b89c3b9ad4284b01e8d00202d42
|
|
12
|
+
9b287611156b7529769e739ce0aed455b216a5e3
|
|
13
|
+
69c403e947feef0a9f974fe42fc79de5f7794eec
|
|
14
|
+
e071c7d4384e3ef1c95c624de710fc3ebfdc5ef6
|
|
15
|
+
6f4308c986319efaf29a4284746b0152dc1265bd
|
|
16
|
+
e2b09f4084cb7a0c3558928ce97ef0a89748e577
|
|
17
|
+
d0f950a112e2f151581fa8037d37ecf69e292530
|
|
18
|
+
f551bc5f4a8bbf27464bb3136d32ae869de2ac0a
|
|
19
|
+
4eae45347e6a118520be85892984afff2bda36aa
|
|
20
|
+
b61da9f98ccfef415d3773ff7bfc20c2ab695d53
|
|
21
|
+
88929f0f1dec04544328e468d0b7b95f646d2ee2
|
|
22
|
+
b6e3034b5b72ef3db975bf3a039f1c8c1d023789
|
|
23
|
+
a710112ae1670e76681200ad6475c56ee91e1725
|
|
24
|
+
59be294e6a87378618064ef055520cbab7648c94
|
|
25
|
+
ef787f1134d77b01a334d059d578ce2f56e34e5a
|
|
26
|
+
861931b0e75cd1d54270b535f1773d80923a904f
|
|
27
|
+
a5cf52b5610589ce56399da9d2c5886bd3a669c5
|
|
28
|
+
abb4b583d8c81eb8d2f3d3123cfda23cb9e47953
|
|
29
|
+
e7ead2dcd8fb1c6df089eb1b42a05fd50db69466
|
|
30
|
+
37a2bb563edcb68b5a2e7e7ec6331bec7e9d8a76
|
|
31
|
+
5ad8d7b7b5acc4abdc4050cae38a58782c48e56f
|
|
32
|
+
9b311151154a36322369a321f3c11512f50539b5
|
|
33
|
+
c093369d557e59fd212e99e01150ebbb3a2fc6ea
|
|
34
|
+
5cbc7919445d6d7121cc231ea37c8ed1ca21365e
|
|
35
|
+
de595f2618657b0decbcf9fe827168d0e1e8e38b
|
|
36
|
+
cfc1080e75baf2a8086322420666be685d6886a8
|
|
37
|
+
2c364de0bfd397132f7a2c5c751b8e8df829cfe1
|
|
38
|
+
5ebb1cb7f2613c820b83dfae3f90591a17fcc930
|
|
39
|
+
0b8d7677d3fd396f515dd5f46cdb47c3da3885bd
|
|
40
|
+
bb6ba73a39bc166c6a9968476999a9c08b63ccc8
|
|
41
|
+
5c6dfea7b2dd5219901141935f29577bbf1fef55
|
|
42
|
+
9b3e5921d0b9d05fcd422202c5e3aef6db01e205
|
|
43
|
+
4caa83e882a1bf32c2e8da89608ad57b4a5dc136
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
## Checklist
|
|
7
7
|
<!--- We appreciate your help and want to give you credit. Place an `x` in the boxes below as you complete them. -->
|
|
8
8
|
- [ ] I added this contribution to the `changelog.md` file.
|
|
9
|
-
- [ ] I added my name to the `AUTHORS` file (or it's already there).
|
|
9
|
+
- [ ] I added my name to the `mycli/AUTHORS.txt` file (or it's already there).
|
|
10
10
|
- [ ] To lint and format the code, I ran
|
|
11
11
|
```bash
|
|
12
12
|
uv run ruff check && uv run ruff format && uv run mypy --install-types .
|
mycli-2.28.1/AGENTS.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Mycli
|
|
2
|
+
|
|
3
|
+
Rich MySQL terminal client with auto-completion, syntax highlighting, and dataframes.
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
/ # repository root
|
|
8
|
+
├── .github/ # GitHub Actions and configuration
|
|
9
|
+
├── pyproject.toml # project configuration
|
|
10
|
+
├── doc/ # documentation
|
|
11
|
+
├── doc/cookbook.md # recipes for how to configure and use mycli
|
|
12
|
+
├── doc/key_bindings.md # documentation of key binding behaviors
|
|
13
|
+
├── doc/known_bugs.md # documentation of known bugs and limitations
|
|
14
|
+
├── doc/llm.md # documentation on how to use LLM features
|
|
15
|
+
├── doc/transforms.md # documentation on how to use dataframe transform/plot features
|
|
16
|
+
├── doc/screenshots/ # screenshots for documentation
|
|
17
|
+
├── mycli/ # application source
|
|
18
|
+
├── mycli/__init__.py # provides version number
|
|
19
|
+
├── mycli/app_state.py # `AppStateMixin` application state mixin and related functions
|
|
20
|
+
├── mycli/cli_runner.py # connects and dispatches main modes based on CLI arguments
|
|
21
|
+
├── mycli/client_commands.py # special commands which must be registered separately
|
|
22
|
+
├── mycli/client_connection.py # `ClientConnectionMixin` mixin for establishing the database connection
|
|
23
|
+
├── mycli/client_query.py # `ClientQueryMixin` mixin for running queries and refreshing completions
|
|
24
|
+
├── mycli/client.py # the `MyCli` "god class"
|
|
25
|
+
├── mycli/compat.py # OS compatibility helpers
|
|
26
|
+
├── mycli/config.py # configuration file readers and utilities
|
|
27
|
+
├── mycli/constants.py # shared constants
|
|
28
|
+
├── mycli/main.py # processes CLI arguments
|
|
29
|
+
├── mycli/main_modes/ # main execution paths
|
|
30
|
+
├── mycli/main_modes/batch.py # `--batch` mode
|
|
31
|
+
├── mycli/main_modes/checkup.py # `--checkup` mode
|
|
32
|
+
├── mycli/main_modes/completions.py # `--completions` mode
|
|
33
|
+
├── mycli/main_modes/execute.py # `--execute` mode
|
|
34
|
+
├── mycli/main_modes/list_dsn.py # `--list-dsn` mode
|
|
35
|
+
├── mycli/main_modes/repl.py # interactive REPL mode
|
|
36
|
+
├── mycli/myclirc # project-level configuration file
|
|
37
|
+
├── mycli/output.py # `OutputMixin` mixin for feedback and output of query results
|
|
38
|
+
├── mycli/packages/ # application packages
|
|
39
|
+
├── mycli/packages/completion/completion_engine.py # implementation of completion suggestions
|
|
40
|
+
├── mycli/packages/completion/completion_refresher.py # populates a `SQLCompleter` object in a background thread
|
|
41
|
+
├── mycli/packages/completion/schema_prefetcher.py # background prefetcher for multi-schema auto-completion
|
|
42
|
+
├── mycli/packages/completion/sql_completer.py # finds SQL completion candidates
|
|
43
|
+
├── mycli/packages/credentials/password_sources.py # password sources and precedence
|
|
44
|
+
├── mycli/packages/dataframes/completion.py # completions for `.|` transforms
|
|
45
|
+
├── mycli/packages/dataframes/transform.py # implements `.|` transforms
|
|
46
|
+
├── mycli/packages/execution/background_runner.py # run queries in the background, with query state and timing updates
|
|
47
|
+
├── mycli/packages/execution/sql_execute.py # `SQLExecute` class and friends
|
|
48
|
+
├── mycli/packages/integrations/ # integrations with fzf, Boundary, Kubernetes, macOS, OpenSSH, and Vault
|
|
49
|
+
├── mycli/packages/prompt_toolkit/fzf_history.py # uses fzf integration to serach the prompt_toolkit history
|
|
50
|
+
├── mycli/packages/prompt_toolkit/history.py # extends the prompt_toolkit history class
|
|
51
|
+
├── mycli/packages/prompt_toolkit/key_bindings.py # prompt_toolkit key bindings
|
|
52
|
+
├── mycli/packages/prompt_toolkit/multiline.py # prompt_toolkit multiline input
|
|
53
|
+
├── mycli/packages/prompt_toolkit/style.py # prompt_toolkit (and Pygments) styles
|
|
54
|
+
├── mycli/packages/prompt_toolkit/toolbar.py # prompt_toolkit bottom toolbar
|
|
55
|
+
├── mycli/packages/prompt_toolkit/utils.py # general utility functions for prompt_toolkit
|
|
56
|
+
├── mycli/packages/pygments/mycli_lexer.py # extends `MySqlLexer` from Pygments
|
|
57
|
+
├── mycli/packages/redirection/ # implementation of shell-style redirects
|
|
58
|
+
├── mycli/packages/special_commands/ # implementation of mycli special commands
|
|
59
|
+
├── mycli/packages/sql_result/sql_result.py # the `SQLResult` dataclass for holding responses
|
|
60
|
+
├── mycli/packages/tabular_output/ # extends cli_helper with additional output formats
|
|
61
|
+
├── mycli/packages/utils/batch_utils.py # utilities for `--batch` mode
|
|
62
|
+
├── mycli/packages/utils/cli_utils.py # utilities for parsing CLI arguments
|
|
63
|
+
├── mycli/packages/utils/interactive_utils.py # utilities for confirming on destructive statements
|
|
64
|
+
├── mycli/packages/utils/key_binding_utils.py # handlers for key bindings and related special commands
|
|
65
|
+
├── mycli/packages/utils/keyring_utils.py # saved credential utilities
|
|
66
|
+
├── mycli/packages/utils/path_utils.py # utilities for files, including completion suggestions
|
|
67
|
+
├── mycli/packages/utils/sql_utils.py # utilities for parsing SQL statements
|
|
68
|
+
├── mycli/packages/utils/string_utils.py # generic string utilities
|
|
69
|
+
├── mycli/resources/completions/ # shell completions for CLI interface
|
|
70
|
+
├── mycli/types.py # shared types
|
|
71
|
+
├── mycli_test/features/ # behave tests
|
|
72
|
+
├── mycli_test/myclirc # mycli configuration used for tests
|
|
73
|
+
├── mycli_test/mylogin.cnf # `mylogin.cnf` example used for tests
|
|
74
|
+
├── mycli_test/pytests/ # pytest tests
|
|
75
|
+
├── mycli_test/pytests/conftest.py # pytest configuration
|
|
76
|
+
└── mycli_test/utils.py # shared utilities for tests
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
### Python
|
|
81
|
+
|
|
82
|
+
#### Python Dependency Management
|
|
83
|
+
|
|
84
|
+
This repo uses `uv` for dependency management. **Always** prefix Python
|
|
85
|
+
commands with `uv run`. Example:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
env -u PYTHONPATH uv run -- python script.py
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### Python Typing
|
|
92
|
+
|
|
93
|
+
This repo uses type annotations which are checked by `mypy`. **Always** add
|
|
94
|
+
type annotations, and always check new code with `env -u PYTHONPATH uv run -- mypy --install-types --non-interactive script.py`.
|
|
95
|
+
|
|
96
|
+
Use lower-case type annotations such as `tuple`, not upper-case type
|
|
97
|
+
annotations such as `Tuple`.
|
|
98
|
+
|
|
99
|
+
Use `Type | None` instead of `Optional[Type]`.
|
|
100
|
+
|
|
101
|
+
#### Python Testing
|
|
102
|
+
|
|
103
|
+
Tests are coordinated by `tox`, and include both `pytest` and `behave` tests.
|
|
104
|
+
To run the full test suite, execute `env -u PYTHONPATH uv run -- tox`.
|
|
105
|
+
|
|
106
|
+
#### Python Compatibility
|
|
107
|
+
|
|
108
|
+
Use Python features available from Python 3.11 through Python 3.14.
|
|
109
|
+
Compatibility with Python 3.9 is not needed. Compatibility with Python
|
|
110
|
+
3.10 is not needed.
|
|
111
|
+
|
|
112
|
+
#### Python Style
|
|
113
|
+
|
|
114
|
+
Import style: prefer `from package import name` over `import package.name as name`.
|
|
115
|
+
|
|
116
|
+
Quoting style: prefer single quotes for new code, but do not remove double quotes
|
|
117
|
+
from existing code.
|
|
118
|
+
|
|
119
|
+
#### Python Environment
|
|
120
|
+
|
|
121
|
+
* Package manager: `uv` (not pip)
|
|
122
|
+
* Formatter: `env -u PYTHONPATH uv run -- ruff format`
|
|
123
|
+
* Linter: `env -u PYTHONPATH uv run -- ruff check`
|
|
124
|
+
* Type checker: `env -u PYTHONPATH uv run -- mypy --install-types --non-interactive`
|
|
125
|
+
|
|
126
|
+
### Git Workflows
|
|
127
|
+
|
|
128
|
+
#### Git Commit Messages
|
|
129
|
+
|
|
130
|
+
* Use the present tense.
|
|
131
|
+
* Keep the first line under 50 characters in length.
|
|
132
|
+
* Keep the second line blank.
|
|
133
|
+
* Keep all other lines under 72 characters in length.
|
|
134
|
+
* Reference issue numbers when available.
|
|
135
|
+
|
|
136
|
+
#### Generating PRs
|
|
137
|
+
|
|
138
|
+
When generating a PR, follow the instructions in `.github/PULL_REQUEST_TEMPLATE.md`:
|
|
139
|
+
|
|
140
|
+
* Add new author names to `mycli/AUTHORS.txt`.
|
|
141
|
+
* Add a new entry to `changelog.md`.
|
|
142
|
+
|
|
143
|
+
### Code Comments
|
|
144
|
+
|
|
145
|
+
Keep comments concise and direct. Use full sentences, ending with a period.
|
|
146
|
+
|
|
147
|
+
### See Also
|
|
148
|
+
|
|
149
|
+
See also the file `CONTRIBUTING.md`.
|
mycli-2.28.1/AUTHORS.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
See [AUTHORS.txt](mycli/AUTHORS.txt)
|
|
@@ -126,7 +126,7 @@ readlink -f $(which ex)
|
|
|
126
126
|
# GitHub PR checklist
|
|
127
127
|
|
|
128
128
|
* add the contribution to `changelog.md`
|
|
129
|
-
* add your name to the `AUTHORS` file (or make sure it is already there)
|
|
129
|
+
* add your name to the `mycli/AUTHORS.txt` file (or make sure it is already there)
|
|
130
130
|
* run
|
|
131
131
|
|
|
132
132
|
```bash
|
mycli-2.28.1/MANIFEST.in
ADDED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mycli
|
|
3
|
-
Version: 2.28.
|
|
3
|
+
Version: 2.28.1
|
|
4
4
|
Summary: Rich MySQL terminal client with autocompletion, syntax highlighting, and dataframes
|
|
5
5
|
Author: Mycli Core Team
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
22
23
|
Classifier: Programming Language :: SQL
|
|
23
24
|
Classifier: Topic :: Database
|
|
24
25
|
Classifier: Topic :: Database :: Front-Ends
|
mycli-2.28.1/SPONSORS.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
See [SPONSORS.txt](mycli/SPONSORS.txt)
|
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
v2.28.1 (2026/10/03)
|
|
2
|
+
==============
|
|
3
|
+
|
|
4
|
+
Documentation
|
|
5
|
+
--------
|
|
6
|
+
* Align all uses of one-line app description with `README.md`.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Internal
|
|
10
|
+
--------
|
|
11
|
+
* Add Python 3.15 trove classifier.
|
|
12
|
+
* Move Polars files to `dataframes` package directory.
|
|
13
|
+
* Move various utility files to a `utils` directory.
|
|
14
|
+
* Move various completion files to a `completion` directory.
|
|
15
|
+
* Move `fzf.py` inside a package directory.
|
|
16
|
+
* Move `hybrid_redirection.py` inside a package directory.
|
|
17
|
+
* Move `sql_result.py` inside a package directory.
|
|
18
|
+
* Rename `special` package to `special_commands`.
|
|
19
|
+
* Move various integrations to an `integrations` directory.
|
|
20
|
+
* Move various `prompt_toolkit` extensions to the `ptoolkit` directory.
|
|
21
|
+
* Rename the `ptoolkit` package to `prompt_toolkit`.
|
|
22
|
+
* Move `mycli_lexer.py` to a `pygments` package directory.
|
|
23
|
+
* Move `password_sources.py` to a `credentials` package directory.
|
|
24
|
+
* Create an `execution` package directory for `sql_execute.py` and `background_runner.py`.
|
|
25
|
+
* Add `.txt` to text files without file extensions.
|
|
26
|
+
* Move `test` directory to `mycli_test`.
|
|
27
|
+
* Ignore recent refactoring move commits in `git-blame`.
|
|
28
|
+
* Recast `cli_is_multiline()` as `repl_is_multiline()`.
|
|
29
|
+
* Align some imports and variable names to match filename moves.
|
|
30
|
+
|
|
31
|
+
|
|
1
32
|
v2.28.0 (2026/10/02)
|
|
2
33
|
==============
|
|
3
34
|
|
|
@@ -14,10 +14,10 @@ __lazy_modules__ = [
|
|
|
14
14
|
'mycli.main_modes.completions',
|
|
15
15
|
'mycli.main_modes.execute',
|
|
16
16
|
'mycli.main_modes.list_dsn',
|
|
17
|
-
'mycli.packages.
|
|
18
|
-
'mycli.packages.
|
|
19
|
-
'mycli.password_sources',
|
|
20
|
-
'mycli.vault',
|
|
17
|
+
'mycli.packages.special_commands.dsn_aliases',
|
|
18
|
+
'mycli.packages.utils.cli_utils',
|
|
19
|
+
'mycli.packages.credentials.password_sources',
|
|
20
|
+
'mycli.packages.integrations.vault.vault_credentials',
|
|
21
21
|
]
|
|
22
22
|
|
|
23
23
|
import os
|
|
@@ -35,16 +35,16 @@ from mycli.main_modes.checkup import main_checkup
|
|
|
35
35
|
from mycli.main_modes.completions import main_completions
|
|
36
36
|
from mycli.main_modes.execute import main_execute_from_cli
|
|
37
37
|
from mycli.main_modes.list_dsn import main_list_dsn
|
|
38
|
-
from mycli.packages.
|
|
39
|
-
from mycli.packages.
|
|
40
|
-
from mycli.password_sources import PasswordCandidates
|
|
41
|
-
from mycli.vault import (
|
|
38
|
+
from mycli.packages.credentials.password_sources import PasswordCandidates
|
|
39
|
+
from mycli.packages.integrations.vault.vault_credentials import (
|
|
42
40
|
DEFAULT_VAULT_EXECUTABLE,
|
|
43
41
|
DEFAULT_VAULT_PASSWORD_FIELD,
|
|
44
42
|
DEFAULT_VAULT_USERNAME_FIELD,
|
|
45
43
|
VaultError,
|
|
46
44
|
get_field_from_vault,
|
|
47
45
|
)
|
|
46
|
+
from mycli.packages.special_commands.dsn_aliases import INVALID_DSN_ALIAS_ERROR, is_valid_dsn_alias
|
|
47
|
+
from mycli.packages.utils.cli_utils import is_valid_connection_scheme
|
|
48
48
|
|
|
49
49
|
if TYPE_CHECKING:
|
|
50
50
|
from mycli.main import CliArgs
|
|
@@ -20,12 +20,9 @@ from mycli.app_state import (
|
|
|
20
20
|
normalize_image_protocol,
|
|
21
21
|
normalize_ssl_mode,
|
|
22
22
|
)
|
|
23
|
-
from mycli.boundary_tunnel import BoundaryTunnel
|
|
24
23
|
from mycli.client_commands import ClientCommandsMixin, get_config_property_names
|
|
25
24
|
from mycli.client_connection import ClientConnectionMixin
|
|
26
25
|
from mycli.client_query import ClientQueryMixin
|
|
27
|
-
from mycli.clistyle import style_factory_helpers, style_factory_ptoolkit
|
|
28
|
-
from mycli.completion_refresher import CompletionRefresher
|
|
29
26
|
from mycli.config import (
|
|
30
27
|
get_mylogin_cnf_path,
|
|
31
28
|
open_mylogin_cnf,
|
|
@@ -34,17 +31,20 @@ from mycli.config import (
|
|
|
34
31
|
write_default_config,
|
|
35
32
|
)
|
|
36
33
|
from mycli.constants import DEFAULT_PROMPT
|
|
37
|
-
from mycli.kubectl_tunnel import KubectlTunnel
|
|
38
34
|
from mycli.main_modes import repl as repl_package
|
|
39
35
|
from mycli.output import OutputMixin
|
|
40
|
-
from mycli.packages import
|
|
41
|
-
from mycli.packages.
|
|
42
|
-
from mycli.packages.
|
|
36
|
+
from mycli.packages import special_commands
|
|
37
|
+
from mycli.packages.completion.completion_refresher import CompletionRefresher
|
|
38
|
+
from mycli.packages.completion.schema_prefetcher import SchemaPrefetcher
|
|
39
|
+
from mycli.packages.completion.sql_completer import SQLCompleter
|
|
40
|
+
from mycli.packages.execution.sql_execute import SQLExecute
|
|
41
|
+
from mycli.packages.integrations.boundary.boundary_tunnel import BoundaryTunnel
|
|
42
|
+
from mycli.packages.integrations.kubernetes.kubectl_tunnel import KubectlTunnel
|
|
43
|
+
from mycli.packages.integrations.openssh.ssh_tunnel import SshTunnel
|
|
44
|
+
from mycli.packages.prompt_toolkit.style import style_factory_helpers, style_factory_prompt_toolkit
|
|
45
|
+
from mycli.packages.special_commands.dsn_aliases import DsnAliases
|
|
46
|
+
from mycli.packages.special_commands.favorite_queries import FavoriteQueries
|
|
43
47
|
from mycli.packages.tabular_output import sql_format
|
|
44
|
-
from mycli.schema_prefetcher import SchemaPrefetcher
|
|
45
|
-
from mycli.sqlcompleter import SQLCompleter
|
|
46
|
-
from mycli.sqlexecute import SQLExecute
|
|
47
|
-
from mycli.ssh_tunnel import SshTunnel
|
|
48
48
|
from mycli.types import Query
|
|
49
49
|
|
|
50
50
|
sqlparse.engine.grouping.MAX_GROUPING_DEPTH = None # type: ignore[assignment]
|
|
@@ -56,7 +56,7 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
56
56
|
default_prompt_splitln = r'\u@\h\n(\t):\d>\_'
|
|
57
57
|
max_len_prompt = 45
|
|
58
58
|
prompt_lines: int
|
|
59
|
-
|
|
59
|
+
sql_execute: SQLExecute | None
|
|
60
60
|
numeric_alignment: str
|
|
61
61
|
|
|
62
62
|
# check XDG_CONFIG_HOME exists and not an empty string
|
|
@@ -68,7 +68,7 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
68
68
|
|
|
69
69
|
def __init__(
|
|
70
70
|
self,
|
|
71
|
-
|
|
71
|
+
sql_execute: SQLExecute | None = None,
|
|
72
72
|
prompt: str | None = None,
|
|
73
73
|
toolbar_format: str | None = None,
|
|
74
74
|
logfile: TextIOWrapper | Literal[False] | None = None,
|
|
@@ -79,7 +79,7 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
79
79
|
show_warnings: bool | None = None,
|
|
80
80
|
cli_verbosity: int = 0,
|
|
81
81
|
) -> None:
|
|
82
|
-
self.
|
|
82
|
+
self.sql_execute = sql_execute
|
|
83
83
|
self.ssh_tunnel: SshTunnel | None = None
|
|
84
84
|
self.kubectl_tunnel: KubectlTunnel | None = None
|
|
85
85
|
self.boundary_tunnel: BoundaryTunnel | None = None
|
|
@@ -111,12 +111,12 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
111
111
|
self.key_bindings = c["main"]["key_bindings"]
|
|
112
112
|
self.emacs_ttimeoutlen = c['keys'].as_float('emacs_ttimeoutlen')
|
|
113
113
|
self.vi_ttimeoutlen = c['keys'].as_float('vi_ttimeoutlen')
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
special_commands.set_timing_enabled(c["main"].as_bool("timing"))
|
|
115
|
+
special_commands.set_show_favorite_query(c["main"].as_bool("show_favorite_query"))
|
|
116
116
|
if show_warnings is not None:
|
|
117
|
-
|
|
117
|
+
special_commands.set_show_warnings_enabled(show_warnings)
|
|
118
118
|
else:
|
|
119
|
-
|
|
119
|
+
special_commands.set_show_warnings_enabled(c['main'].as_bool('show_warnings'))
|
|
120
120
|
self.beep_after_seconds = float(c["main"]["beep_after_seconds"] or 0)
|
|
121
121
|
self.default_keepalive_ticks = c['connection'].as_int('default_keepalive_ticks')
|
|
122
122
|
|
|
@@ -150,7 +150,7 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
150
150
|
if cli_verbosity:
|
|
151
151
|
self.verbosity = cli_verbosity
|
|
152
152
|
self.cli_style = c["colors"]
|
|
153
|
-
self.
|
|
153
|
+
self.prompt_toolkit_style = style_factory_prompt_toolkit(self.syntax_style, self.cli_style)
|
|
154
154
|
self.helpers_style = style_factory_helpers(self.syntax_style, self.cli_style)
|
|
155
155
|
self.helpers_warnings_style = style_factory_helpers(self.syntax_style, self.cli_style, warnings=True)
|
|
156
156
|
self.wider_completion_menu = c["main"].as_bool("wider_completion_menu")
|
|
@@ -247,7 +247,7 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
247
247
|
configure_prompt_state(self, c, prompt, toolbar_format)
|
|
248
248
|
self.prompt_session = None
|
|
249
249
|
self.destructive_keywords = destructive_keywords_from_config(c)
|
|
250
|
-
|
|
250
|
+
special_commands.set_destructive_keywords(self.destructive_keywords)
|
|
251
251
|
|
|
252
252
|
def _invalidate_prompt_session(self) -> None:
|
|
253
253
|
if self.prompt_session:
|
|
@@ -262,9 +262,9 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
|
|
|
262
262
|
self.schema_prefetcher.stop()
|
|
263
263
|
except Exception:
|
|
264
264
|
pass
|
|
265
|
-
if self.
|
|
265
|
+
if self.sql_execute is not None:
|
|
266
266
|
try:
|
|
267
|
-
self.
|
|
267
|
+
self.sql_execute.close()
|
|
268
268
|
except Exception:
|
|
269
269
|
pass
|
|
270
270
|
if self.ssh_tunnel is not None:
|
|
@@ -11,19 +11,19 @@ import click
|
|
|
11
11
|
|
|
12
12
|
from mycli.config import write_default_config
|
|
13
13
|
from mycli.main_modes.repl import set_all_external_titles
|
|
14
|
-
from mycli.packages import
|
|
15
|
-
from mycli.packages.
|
|
16
|
-
from mycli.packages.
|
|
17
|
-
from mycli.packages.
|
|
18
|
-
from mycli.packages.
|
|
19
|
-
from mycli.packages.special.main import ArgType, SpecialCommandAlias
|
|
20
|
-
from mycli.packages.special.source import (
|
|
14
|
+
from mycli.packages import special_commands
|
|
15
|
+
from mycli.packages.execution.sql_execute import SQLExecute
|
|
16
|
+
from mycli.packages.prompt_toolkit.history import FileHistoryWithTimestamp
|
|
17
|
+
from mycli.packages.special_commands.main import ArgType, SpecialCommandAlias
|
|
18
|
+
from mycli.packages.special_commands.source import (
|
|
21
19
|
SOURCE_HELP_ROWS,
|
|
22
20
|
parse_source_arguments,
|
|
23
21
|
source_special_command_is_safe,
|
|
24
22
|
)
|
|
25
|
-
from mycli.packages.
|
|
26
|
-
from mycli.
|
|
23
|
+
from mycli.packages.sql_result.sql_result import SQLResult
|
|
24
|
+
from mycli.packages.utils.batch_utils import statements_from_filehandle
|
|
25
|
+
from mycli.packages.utils.interactive_utils import confirm_destructive_query
|
|
26
|
+
from mycli.packages.utils.path_utils import dir_path_exists
|
|
27
27
|
|
|
28
28
|
CONFIG_COMMAND_USAGE = '''Syntax:
|
|
29
29
|
/config get <key>
|
|
@@ -96,7 +96,7 @@ class ClientCommandsMixin:
|
|
|
96
96
|
if TYPE_CHECKING:
|
|
97
97
|
main_formatter: Any
|
|
98
98
|
redirect_formatter: Any
|
|
99
|
-
|
|
99
|
+
sql_execute: Any
|
|
100
100
|
destructive_warning: bool
|
|
101
101
|
destructive_keywords: Any
|
|
102
102
|
config: Any
|
|
@@ -109,7 +109,7 @@ class ClientCommandsMixin:
|
|
|
109
109
|
def echo(self, *args: Any, **kwargs: Any) -> None: ...
|
|
110
110
|
|
|
111
111
|
def register_special_commands(self) -> None:
|
|
112
|
-
|
|
112
|
+
special_commands.register_special_command(
|
|
113
113
|
self.change_db,
|
|
114
114
|
"use",
|
|
115
115
|
"/use <database>",
|
|
@@ -117,7 +117,7 @@ class ClientCommandsMixin:
|
|
|
117
117
|
aliases=[SpecialCommandAlias("\\u", case_sensitive=False)],
|
|
118
118
|
completion_snippet='change databases',
|
|
119
119
|
)
|
|
120
|
-
|
|
120
|
+
special_commands.register_special_command(
|
|
121
121
|
self.manual_reconnect,
|
|
122
122
|
"connect",
|
|
123
123
|
"/connect [database]",
|
|
@@ -126,7 +126,7 @@ class ClientCommandsMixin:
|
|
|
126
126
|
aliases=[SpecialCommandAlias("\\r", case_sensitive=True)],
|
|
127
127
|
completion_snippet='reconnect to server',
|
|
128
128
|
)
|
|
129
|
-
|
|
129
|
+
special_commands.register_special_command(
|
|
130
130
|
self.rehash,
|
|
131
131
|
"rehash",
|
|
132
132
|
"/rehash",
|
|
@@ -135,7 +135,7 @@ class ClientCommandsMixin:
|
|
|
135
135
|
aliases=[SpecialCommandAlias("\\#", case_sensitive=False)],
|
|
136
136
|
completion_snippet='refresh completions',
|
|
137
137
|
)
|
|
138
|
-
|
|
138
|
+
special_commands.register_special_command(
|
|
139
139
|
self.change_table_format,
|
|
140
140
|
"tableformat",
|
|
141
141
|
"/tableformat <format>",
|
|
@@ -144,7 +144,7 @@ class ClientCommandsMixin:
|
|
|
144
144
|
aliases=[SpecialCommandAlias("\\T", case_sensitive=True)],
|
|
145
145
|
completion_snippet='set interactive output format',
|
|
146
146
|
)
|
|
147
|
-
|
|
147
|
+
special_commands.register_special_command(
|
|
148
148
|
self.change_redirect_format,
|
|
149
149
|
"redirectformat",
|
|
150
150
|
"/redirectformat <format>",
|
|
@@ -153,7 +153,7 @@ class ClientCommandsMixin:
|
|
|
153
153
|
aliases=[SpecialCommandAlias("\\Tr", case_sensitive=True)],
|
|
154
154
|
completion_snippet='set redirected output format',
|
|
155
155
|
)
|
|
156
|
-
|
|
156
|
+
special_commands.register_special_command(
|
|
157
157
|
self.execute_from_file,
|
|
158
158
|
"source",
|
|
159
159
|
"/source [options] <file>",
|
|
@@ -161,7 +161,7 @@ class ClientCommandsMixin:
|
|
|
161
161
|
aliases=[SpecialCommandAlias("\\.", case_sensitive=False)],
|
|
162
162
|
completion_snippet='execute queries from file',
|
|
163
163
|
)
|
|
164
|
-
|
|
164
|
+
special_commands.register_special_command(
|
|
165
165
|
self.change_prompt_format,
|
|
166
166
|
"prompt",
|
|
167
167
|
"/prompt [string]",
|
|
@@ -170,7 +170,7 @@ class ClientCommandsMixin:
|
|
|
170
170
|
aliases=[SpecialCommandAlias("\\R", case_sensitive=True)],
|
|
171
171
|
completion_snippet='set prompt format',
|
|
172
172
|
)
|
|
173
|
-
|
|
173
|
+
special_commands.register_special_command(
|
|
174
174
|
self.config_command,
|
|
175
175
|
r'\config',
|
|
176
176
|
'/config <command> [key]',
|
|
@@ -274,13 +274,13 @@ class ClientCommandsMixin:
|
|
|
274
274
|
click.secho("No database selected", err=True, fg="red")
|
|
275
275
|
return
|
|
276
276
|
|
|
277
|
-
assert isinstance(self.
|
|
277
|
+
assert isinstance(self.sql_execute, SQLExecute)
|
|
278
278
|
|
|
279
|
-
if self.
|
|
280
|
-
msg = f'You are already connected to database "{self.
|
|
279
|
+
if self.sql_execute.dbname == arg:
|
|
280
|
+
msg = f'You are already connected to database "{self.sql_execute.dbname}" as user "{self.sql_execute.user}"'
|
|
281
281
|
else:
|
|
282
|
-
self.
|
|
283
|
-
msg = f'You are now connected to database "{self.
|
|
282
|
+
self.sql_execute.change_db(arg)
|
|
283
|
+
msg = f'You are now connected to database "{self.sql_execute.dbname}" as user "{self.sql_execute.user}"'
|
|
284
284
|
|
|
285
285
|
# todo: this jump back to repl.py is a sign that separation is incomplete.
|
|
286
286
|
# also: it should not be needed. Don't titles update on every new prompt?
|
|
@@ -310,7 +310,7 @@ class ClientCommandsMixin:
|
|
|
310
310
|
yield SQLResult(status=str(error))
|
|
311
311
|
return
|
|
312
312
|
|
|
313
|
-
assert isinstance(self.
|
|
313
|
+
assert isinstance(self.sql_execute, SQLExecute)
|
|
314
314
|
executed_statement = False
|
|
315
315
|
with file_h:
|
|
316
316
|
statements = statements_from_filehandle(file_h)
|
|
@@ -324,7 +324,7 @@ class ClientCommandsMixin:
|
|
|
324
324
|
return
|
|
325
325
|
|
|
326
326
|
special_query = query.rstrip(';')
|
|
327
|
-
if
|
|
327
|
+
if special_commands.is_special_command(special_query):
|
|
328
328
|
if not source_arguments.allow_special:
|
|
329
329
|
yield SQLResult(
|
|
330
330
|
status='Special commands are not supported without /source --special.',
|
|
@@ -332,7 +332,7 @@ class ClientCommandsMixin:
|
|
|
332
332
|
)
|
|
333
333
|
return
|
|
334
334
|
if not source_special_command_is_safe(special_query):
|
|
335
|
-
command, _verbosity, _arg =
|
|
335
|
+
command, _verbosity, _arg = special_commands.parse_special_command(special_query)
|
|
336
336
|
yield SQLResult(
|
|
337
337
|
status=f'Special command is never permitted in source files: {command}.',
|
|
338
338
|
is_error=True,
|
|
@@ -345,7 +345,7 @@ class ClientCommandsMixin:
|
|
|
345
345
|
yield SQLResult(command={'name': 'source_show', 'text': special_query})
|
|
346
346
|
else:
|
|
347
347
|
click.secho(f'> {special_query}')
|
|
348
|
-
yield from self.
|
|
348
|
+
yield from self.sql_execute.run(special_query)
|
|
349
349
|
executed_statement = True
|
|
350
350
|
continue
|
|
351
351
|
|
|
@@ -358,7 +358,7 @@ class ClientCommandsMixin:
|
|
|
358
358
|
yield SQLResult(command={'name': 'source_show', 'text': query})
|
|
359
359
|
else:
|
|
360
360
|
click.secho(f'> {query}')
|
|
361
|
-
yield from self.
|
|
361
|
+
yield from self.sql_execute.run(query)
|
|
362
362
|
executed_statement = True
|
|
363
363
|
|
|
364
364
|
def change_prompt_format(self, arg: str, **_) -> list[SQLResult]:
|