harlequin 2.1.3__tar.gz → 2.2.0__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.
- harlequin-2.2.0/.gitignore +181 -0
- {harlequin-2.1.3 → harlequin-2.2.0}/PKG-INFO +39 -43
- {harlequin-2.1.3 → harlequin-2.2.0}/README.md +1 -1
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/actions.py +5 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/adapter.py +26 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/app.py +52 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/app.tcss +13 -5
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/cli.py +1 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/__init__.py +2 -0
- harlequin-2.2.0/harlequin/components/debug_info.py +309 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/help_screen.py +7 -6
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_duckdb/adapter.py +4 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_sqlite/adapter.py +4 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_vscode/__init__.py +1 -0
- harlequin-2.2.0/pyproject.toml +173 -0
- harlequin-2.1.3/pyproject.toml +0 -153
- {harlequin-2.1.3 → harlequin-2.2.0}/LICENSE +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/__init__.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/__main__.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/app_base.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/autocomplete/__init__.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/autocomplete/completers.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/autocomplete/completion.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/autocomplete/constants.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/bindings.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/cache.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/catalog.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/catalog_cache.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/colors.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/code_editor.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/confirm_modal.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/data_catalog/__init__.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/data_catalog/database_tree.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/data_catalog/file_tree.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/data_catalog/s3_tree.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/data_catalog/tree.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/error_modal.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/export_screen.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/help_screen.md +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/history_screen.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/results_viewer.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/components/run_query_bar.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/config.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/config_wizard.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/copy_formats.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/copy_widgets.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/driver.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/editor_cache.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/exception.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/export.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/global.tcss +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/history.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/keymap.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/keys_app.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/keys_app.tcss +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/locale_manager.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/messages.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/options.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/plugins.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/py.typed +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/transaction_mode.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin/windows_timezone.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_duckdb/__init__.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_duckdb/catalog.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_duckdb/cli_options.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_duckdb/completions.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_duckdb/interactions.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_duckdb/py.typed +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_sqlite/__init__.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_sqlite/catalog.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_sqlite/cli_options.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_sqlite/completions.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_sqlite/interactions.py +0 -0
- {harlequin-2.1.3/src → harlequin-2.2.0}/harlequin_sqlite/py.typed +0 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
*.db*
|
|
2
|
+
*.db.wal
|
|
3
|
+
*.csv
|
|
4
|
+
*.json
|
|
5
|
+
*.parquet
|
|
6
|
+
*.sql
|
|
7
|
+
*.sqlite
|
|
8
|
+
!tests/data/**/*.db
|
|
9
|
+
!tests/data/**/*.csv
|
|
10
|
+
!tests/data/**/*.json
|
|
11
|
+
!tests/data/**/*.parquet
|
|
12
|
+
!tests/data/**/*.sql
|
|
13
|
+
Pipfile
|
|
14
|
+
snapshot_report.html
|
|
15
|
+
.harlequin.toml
|
|
16
|
+
.profiles
|
|
17
|
+
|
|
18
|
+
# Byte-compiled / optimized / DLL files
|
|
19
|
+
__pycache__/
|
|
20
|
+
*.py[cod]
|
|
21
|
+
*$py.class
|
|
22
|
+
|
|
23
|
+
# C extensions
|
|
24
|
+
*.so
|
|
25
|
+
!tests/data/**/*.so
|
|
26
|
+
|
|
27
|
+
# Distribution / packaging
|
|
28
|
+
.Python
|
|
29
|
+
build/
|
|
30
|
+
develop-eggs/
|
|
31
|
+
dist/
|
|
32
|
+
downloads/
|
|
33
|
+
eggs/
|
|
34
|
+
.eggs/
|
|
35
|
+
lib/
|
|
36
|
+
lib64/
|
|
37
|
+
parts/
|
|
38
|
+
sdist/
|
|
39
|
+
var/
|
|
40
|
+
wheels/
|
|
41
|
+
share/python-wheels/
|
|
42
|
+
*.egg-info/
|
|
43
|
+
.installed.cfg
|
|
44
|
+
*.egg
|
|
45
|
+
MANIFEST
|
|
46
|
+
|
|
47
|
+
# PyInstaller
|
|
48
|
+
# Usually these files are written by a python script from a template
|
|
49
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
50
|
+
*.manifest
|
|
51
|
+
*.spec
|
|
52
|
+
|
|
53
|
+
# Installer logs
|
|
54
|
+
pip-log.txt
|
|
55
|
+
pip-delete-this-directory.txt
|
|
56
|
+
|
|
57
|
+
# Unit test / coverage reports
|
|
58
|
+
htmlcov/
|
|
59
|
+
.tox/
|
|
60
|
+
.nox/
|
|
61
|
+
.coverage
|
|
62
|
+
.coverage.*
|
|
63
|
+
.cache
|
|
64
|
+
nosetests.xml
|
|
65
|
+
coverage.xml
|
|
66
|
+
*.cover
|
|
67
|
+
*.py,cover
|
|
68
|
+
.hypothesis/
|
|
69
|
+
.pytest_cache/
|
|
70
|
+
cover/
|
|
71
|
+
|
|
72
|
+
# Translations
|
|
73
|
+
*.mo
|
|
74
|
+
*.pot
|
|
75
|
+
|
|
76
|
+
# Django stuff:
|
|
77
|
+
*.log
|
|
78
|
+
local_settings.py
|
|
79
|
+
db.sqlite3
|
|
80
|
+
db.sqlite3-journal
|
|
81
|
+
|
|
82
|
+
# Flask stuff:
|
|
83
|
+
instance/
|
|
84
|
+
.webassets-cache
|
|
85
|
+
|
|
86
|
+
# Scrapy stuff:
|
|
87
|
+
.scrapy
|
|
88
|
+
|
|
89
|
+
# Sphinx documentation
|
|
90
|
+
docs/_build/
|
|
91
|
+
|
|
92
|
+
# PyBuilder
|
|
93
|
+
.pybuilder/
|
|
94
|
+
target/
|
|
95
|
+
|
|
96
|
+
# Jupyter Notebook
|
|
97
|
+
.ipynb_checkpoints
|
|
98
|
+
|
|
99
|
+
# IPython
|
|
100
|
+
profile_default/
|
|
101
|
+
ipython_config.py
|
|
102
|
+
|
|
103
|
+
# pyenv
|
|
104
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
105
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
106
|
+
# .python-version
|
|
107
|
+
|
|
108
|
+
# pipenv
|
|
109
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
110
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
111
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
112
|
+
# install all needed dependencies.
|
|
113
|
+
#Pipfile.lock
|
|
114
|
+
|
|
115
|
+
# poetry
|
|
116
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
117
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
118
|
+
# commonly ignored for libraries.
|
|
119
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
120
|
+
#poetry.lock
|
|
121
|
+
|
|
122
|
+
# pdm
|
|
123
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
124
|
+
#pdm.lock
|
|
125
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
126
|
+
# in version control.
|
|
127
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
128
|
+
.pdm.toml
|
|
129
|
+
|
|
130
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
131
|
+
__pypackages__/
|
|
132
|
+
|
|
133
|
+
# Celery stuff
|
|
134
|
+
celerybeat-schedule
|
|
135
|
+
celerybeat.pid
|
|
136
|
+
|
|
137
|
+
# SageMath parsed files
|
|
138
|
+
*.sage.py
|
|
139
|
+
|
|
140
|
+
# Environments
|
|
141
|
+
.env
|
|
142
|
+
.venv
|
|
143
|
+
env/
|
|
144
|
+
venv/
|
|
145
|
+
ENV/
|
|
146
|
+
env.bak/
|
|
147
|
+
venv.bak/
|
|
148
|
+
|
|
149
|
+
# Spyder project settings
|
|
150
|
+
.spyderproject
|
|
151
|
+
.spyproject
|
|
152
|
+
|
|
153
|
+
# Rope project settings
|
|
154
|
+
.ropeproject
|
|
155
|
+
|
|
156
|
+
# mkdocs documentation
|
|
157
|
+
/site
|
|
158
|
+
|
|
159
|
+
# mypy
|
|
160
|
+
.mypy_cache/
|
|
161
|
+
.dmypy.json
|
|
162
|
+
dmypy.json
|
|
163
|
+
|
|
164
|
+
# ruff
|
|
165
|
+
.ruff_cache
|
|
166
|
+
|
|
167
|
+
# Pyre type checker
|
|
168
|
+
.pyre/
|
|
169
|
+
|
|
170
|
+
# pytype static type analyzer
|
|
171
|
+
.pytype/
|
|
172
|
+
|
|
173
|
+
# Cython debug symbols
|
|
174
|
+
cython_debug/
|
|
175
|
+
|
|
176
|
+
# PyCharm
|
|
177
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
178
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
179
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
180
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
181
|
+
#.idea/
|
|
@@ -1,56 +1,53 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: harlequin
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: The SQL IDE for Your Terminal.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
Project-URL: Homepage, https://harlequin.sh
|
|
6
|
+
Project-URL: Documentation, https://harlequin.sh/docs/getting-started/index
|
|
7
|
+
Project-URL: Repository, https://github.com/tconbeer/harlequin
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/tconbeer/harlequin/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/tconbeer/harlequin/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Ted Conbeer <tconbeer@users.noreply.github.com>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: harlequin,ide,sql,tui
|
|
14
|
+
Requires-Python: <3.14,>=3.9
|
|
15
|
+
Requires-Dist: click==8.1.8
|
|
16
|
+
Requires-Dist: duckdb>=0.8.0
|
|
17
|
+
Requires-Dist: importlib-metadata>=8.0; python_version < '3.10'
|
|
18
|
+
Requires-Dist: numpy<2.1.0,>=2.0.0; python_version < '3.10'
|
|
19
|
+
Requires-Dist: numpy<2.3.0,>=2.1.0; python_version >= '3.10'
|
|
20
|
+
Requires-Dist: platformdirs<5.0,>=3.10
|
|
21
|
+
Requires-Dist: pyarrow>=18.1.0; python_version >= '3.12'
|
|
22
|
+
Requires-Dist: questionary==2.0.1
|
|
23
|
+
Requires-Dist: rich-click==1.8.5
|
|
24
|
+
Requires-Dist: shandy-sqlfmt>=0.19.0
|
|
25
|
+
Requires-Dist: textual-fastdatatable==0.12.0
|
|
26
|
+
Requires-Dist: textual-textarea==0.15.0
|
|
27
|
+
Requires-Dist: textual==0.89.1
|
|
28
|
+
Requires-Dist: tomlkit<0.14.0,>=0.12.5
|
|
29
|
+
Requires-Dist: tree-sitter-sql==0.3.7
|
|
30
|
+
Requires-Dist: tree-sitter<0.25.0,>=0.23.0
|
|
17
31
|
Provides-Extra: adbc
|
|
32
|
+
Requires-Dist: harlequin-adbc; extra == 'adbc'
|
|
18
33
|
Provides-Extra: bigquery
|
|
34
|
+
Requires-Dist: harlequin-bigquery; extra == 'bigquery'
|
|
19
35
|
Provides-Extra: cassandra
|
|
36
|
+
Requires-Dist: harlequin-cassandra; extra == 'cassandra'
|
|
20
37
|
Provides-Extra: databricks
|
|
38
|
+
Requires-Dist: harlequin-databricks; extra == 'databricks'
|
|
21
39
|
Provides-Extra: mysql
|
|
40
|
+
Requires-Dist: harlequin-mysql; extra == 'mysql'
|
|
22
41
|
Provides-Extra: nebulagraph
|
|
42
|
+
Requires-Dist: harlequin-nebulagraph; extra == 'nebulagraph'
|
|
23
43
|
Provides-Extra: odbc
|
|
44
|
+
Requires-Dist: harlequin-odbc; extra == 'odbc'
|
|
24
45
|
Provides-Extra: postgres
|
|
46
|
+
Requires-Dist: harlequin-postgres; extra == 'postgres'
|
|
25
47
|
Provides-Extra: s3
|
|
48
|
+
Requires-Dist: boto3==1.34.22; extra == 's3'
|
|
26
49
|
Provides-Extra: trino
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist: click (==8.1.8)
|
|
29
|
-
Requires-Dist: duckdb (>=0.8.0)
|
|
30
|
-
Requires-Dist: harlequin-adbc (>=0.1) ; extra == "adbc"
|
|
31
|
-
Requires-Dist: harlequin-bigquery (>=1.0.3) ; extra == "bigquery"
|
|
32
|
-
Requires-Dist: harlequin-cassandra (>=0.1.2) ; extra == "cassandra"
|
|
33
|
-
Requires-Dist: harlequin-databricks (>=0.5.2) ; extra == "databricks"
|
|
34
|
-
Requires-Dist: harlequin-mysql (>=1.0) ; extra == "mysql"
|
|
35
|
-
Requires-Dist: harlequin-nebulagraph (>=0.4.1) ; extra == "nebulagraph"
|
|
36
|
-
Requires-Dist: harlequin-odbc (>=0.2) ; extra == "odbc"
|
|
37
|
-
Requires-Dist: harlequin-postgres (>=1.0) ; extra == "postgres"
|
|
38
|
-
Requires-Dist: harlequin-trino (>=0.1) ; extra == "trino"
|
|
39
|
-
Requires-Dist: importlib_metadata (>=8.0) ; python_full_version < "3.10.0"
|
|
40
|
-
Requires-Dist: numpy (>=2.0.0,<2.1.0) ; python_full_version < "3.10.0"
|
|
41
|
-
Requires-Dist: numpy (>=2.1.0,<2.3.0) ; python_full_version >= "3.10.0"
|
|
42
|
-
Requires-Dist: platformdirs (>=3.10,<5.0)
|
|
43
|
-
Requires-Dist: pyarrow (>=18.1.0) ; python_full_version >= "3.12.0"
|
|
44
|
-
Requires-Dist: questionary (>=2.0.1,<3.0.0)
|
|
45
|
-
Requires-Dist: rich-click (==1.8.5)
|
|
46
|
-
Requires-Dist: shandy-sqlfmt (>=0.19.0)
|
|
47
|
-
Requires-Dist: textual (==0.89.1)
|
|
48
|
-
Requires-Dist: textual-fastdatatable (==0.12.0)
|
|
49
|
-
Requires-Dist: textual-textarea (==0.15.0)
|
|
50
|
-
Requires-Dist: tomlkit (>=0.12.5,<0.14.0)
|
|
51
|
-
Requires-Dist: tree-sitter (>=0.23.0,<0.25.0)
|
|
52
|
-
Requires-Dist: tree-sitter-sql (==0.3.7)
|
|
53
|
-
Project-URL: Repository, https://github.com/tconbeer/harlequin
|
|
50
|
+
Requires-Dist: harlequin-trino; extra == 'trino'
|
|
54
51
|
Description-Content-Type: text/markdown
|
|
55
52
|
|
|
56
53
|
# Harlequin
|
|
@@ -100,7 +97,7 @@ Alternatively, if you know what you're doing, after installing Python 3.9 or abo
|
|
|
100
97
|
pip install harlequin
|
|
101
98
|
```
|
|
102
99
|
|
|
103
|
-
There is also a [Homebrew formula](https://formulae.brew.sh/formula/harlequin) for Harlequin, although this is maintained by the community and is not as rigorously tested as the Python installations. Note that the formula includes several Harlequin adapter packages (Postgres, MySQL, and ODBC) and their dependencies, which is convenient but increases the application size.
|
|
100
|
+
There is also a [Homebrew formula](https://formulae.brew.sh/formula/harlequin) for Harlequin, although this is maintained by the community and is not as rigorously tested as the Python installations. Note that the formula includes several Harlequin adapter packages (Postgres, MySQL/MariaDB, and ODBC) and their dependencies, which is convenient but increases the application size.
|
|
104
101
|
|
|
105
102
|
```bash
|
|
106
103
|
brew install harlequin
|
|
@@ -213,4 +210,3 @@ Please consider [sponsoring Harlequin's author](https://github.com/sponsors/tcon
|
|
|
213
210
|
Thanks for your interest in Harlequin! Harlequin is primarily maintained by [Ted Conbeer](https://github.com/tconbeer), but he welcomes all contributions!
|
|
214
211
|
|
|
215
212
|
Please see [`CONTRIBUTING.md`](./CONTRIBUTING.md) for more information.
|
|
216
|
-
|
|
@@ -45,7 +45,7 @@ Alternatively, if you know what you're doing, after installing Python 3.9 or abo
|
|
|
45
45
|
pip install harlequin
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
There is also a [Homebrew formula](https://formulae.brew.sh/formula/harlequin) for Harlequin, although this is maintained by the community and is not as rigorously tested as the Python installations. Note that the formula includes several Harlequin adapter packages (Postgres, MySQL, and ODBC) and their dependencies, which is convenient but increases the application size.
|
|
48
|
+
There is also a [Homebrew formula](https://formulae.brew.sh/formula/harlequin) for Harlequin, although this is maintained by the community and is not as rigorously tested as the Python installations. Note that the formula includes several Harlequin adapter packages (Postgres, MySQL/MariaDB, and ODBC) and their dependencies, which is convenient but increases the application size.
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
brew install harlequin
|
|
@@ -68,6 +68,11 @@ HARLEQUIN_ACTIONS = {
|
|
|
68
68
|
target=None,
|
|
69
69
|
action="toggle_full_screen",
|
|
70
70
|
),
|
|
71
|
+
"show_debug_info": Action(
|
|
72
|
+
target=None,
|
|
73
|
+
action="show_debug_info",
|
|
74
|
+
description="Debug Info",
|
|
75
|
+
),
|
|
71
76
|
"show_query_history": Action(
|
|
72
77
|
target=None,
|
|
73
78
|
action="show_query_history",
|
|
@@ -207,12 +207,21 @@ class HarlequinAdapter(ABC):
|
|
|
207
207
|
disregard any extra (unexpected) kwargs. They should not rely on the
|
|
208
208
|
option's default values, as those will not be passed by the CLI when
|
|
209
209
|
initializing the adapter.
|
|
210
|
+
|
|
211
|
+
Adapters can provide client-side (Harlequin adapter) details using the
|
|
212
|
+
ADAPTER_DETAILS class variable. It is expected to be formatted as markdown.
|
|
213
|
+
|
|
214
|
+
Adapters can also provide server-side (DB driver) details using the
|
|
215
|
+
ADAPTER_DRIVER_DETAILS class variable. It is expected to be formatted
|
|
216
|
+
as markdown.
|
|
210
217
|
"""
|
|
211
218
|
|
|
212
219
|
ADAPTER_OPTIONS: list[HarlequinAdapterOption] | None = None
|
|
213
220
|
COPY_FORMATS: list[HarlequinCopyFormat] | None = None
|
|
214
221
|
"""DEPRECATED. Adapter Copy formats are now ignored by Harlequin."""
|
|
215
222
|
IMPLEMENTS_CANCEL = False
|
|
223
|
+
ADAPTER_DETAILS: str | None = None
|
|
224
|
+
ADAPTER_DRIVER_DETAILS: str | None = None
|
|
216
225
|
|
|
217
226
|
@abstractmethod
|
|
218
227
|
def __init__(self, conn_str: Sequence[str], **options: Any) -> None:
|
|
@@ -267,3 +276,20 @@ class HarlequinAdapter(ABC):
|
|
|
267
276
|
also provide options for customizing the Export dialog GUI.
|
|
268
277
|
"""
|
|
269
278
|
return self.COPY_FORMATS is not None
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def provides_details(self) -> bool:
|
|
282
|
+
"""
|
|
283
|
+
True if the adapter provides an optional description of itself, visible
|
|
284
|
+
on Harlequin's debugging info screen, NOT including
|
|
285
|
+
driver or connection details, which should be ADAPTER_DRIVER_DETAILS.
|
|
286
|
+
"""
|
|
287
|
+
return self.ADAPTER_DETAILS is not None
|
|
288
|
+
|
|
289
|
+
@property
|
|
290
|
+
def provides_driver_details(self) -> bool:
|
|
291
|
+
"""
|
|
292
|
+
True if the adapter provides an optional description of its driver
|
|
293
|
+
or connection.
|
|
294
|
+
"""
|
|
295
|
+
return self.ADAPTER_DRIVER_DETAILS is not None
|
|
@@ -57,6 +57,7 @@ from harlequin.catalog_cache import (
|
|
|
57
57
|
from harlequin.components import (
|
|
58
58
|
CodeEditor,
|
|
59
59
|
DataCatalog,
|
|
60
|
+
DebugInfoScreen,
|
|
60
61
|
EditorCollection,
|
|
61
62
|
ErrorModal,
|
|
62
63
|
ExportScreen,
|
|
@@ -69,6 +70,12 @@ from harlequin.components import (
|
|
|
69
70
|
from harlequin.components.confirm_modal import ConfirmModal
|
|
70
71
|
from harlequin.components.data_catalog import ContextMenu
|
|
71
72
|
from harlequin.components.data_catalog.tree import HarlequinTree
|
|
73
|
+
from harlequin.components.debug_info import AdapterDebugInfo, HarlequinDebugInfo
|
|
74
|
+
from harlequin.config import (
|
|
75
|
+
get_config_for_profile,
|
|
76
|
+
get_highest_priority_existing_config_file,
|
|
77
|
+
load_config,
|
|
78
|
+
)
|
|
72
79
|
from harlequin.copy_formats import HARLEQUIN_COPY_FORMATS, WINDOWS_COPY_FORMATS
|
|
73
80
|
from harlequin.driver import HarlequinDriver
|
|
74
81
|
from harlequin.editor_cache import BufferState, Cache
|
|
@@ -182,6 +189,7 @@ class Harlequin(AppBase):
|
|
|
182
189
|
def __init__(
|
|
183
190
|
self,
|
|
184
191
|
adapter: HarlequinAdapter,
|
|
192
|
+
profile_name: str | None = None,
|
|
185
193
|
*,
|
|
186
194
|
keymap_names: Sequence[str] | None = None,
|
|
187
195
|
user_defined_keymaps: Sequence[HarlequinKeyMap] | None = None,
|
|
@@ -201,6 +209,7 @@ class Harlequin(AppBase):
|
|
|
201
209
|
watch_css=watch_css,
|
|
202
210
|
)
|
|
203
211
|
self.adapter = adapter
|
|
212
|
+
self.profile_name = profile_name
|
|
204
213
|
self.connection_hash = connection_hash
|
|
205
214
|
self.history: History | None = None
|
|
206
215
|
self.show_files = show_files
|
|
@@ -279,6 +288,8 @@ class Harlequin(AppBase):
|
|
|
279
288
|
and self.editor._has_focus_within
|
|
280
289
|
):
|
|
281
290
|
self.editor.text_input._pause_blink(visible=True)
|
|
291
|
+
|
|
292
|
+
## TODO: PREVENT DUPLICATE SCREENS HERE.
|
|
282
293
|
return super().push_screen( # type: ignore[no-any-return,call-overload]
|
|
283
294
|
screen,
|
|
284
295
|
callback=callback,
|
|
@@ -951,6 +962,47 @@ class Harlequin(AppBase):
|
|
|
951
962
|
def action_show_help_screen(self) -> None:
|
|
952
963
|
self.push_screen(HelpScreen(id="help_screen"))
|
|
953
964
|
|
|
965
|
+
def action_show_debug_info(self) -> None:
|
|
966
|
+
SCREEN_ID = "debug_info_screen"
|
|
967
|
+
if self.screen.id == SCREEN_ID:
|
|
968
|
+
# already showing this screen.
|
|
969
|
+
return
|
|
970
|
+
|
|
971
|
+
config_path = get_highest_priority_existing_config_file()
|
|
972
|
+
config = load_config(config_path)
|
|
973
|
+
profile_name = self.profile_name
|
|
974
|
+
active_profile_config, _ = get_config_for_profile(config_path, profile_name)
|
|
975
|
+
active_profile_name = profile_name or config.get("default_profile")
|
|
976
|
+
adapter_options = getattr(self.adapter, "ADAPTER_OPTIONS", None)
|
|
977
|
+
adapter_type = type(self.adapter).__name__
|
|
978
|
+
|
|
979
|
+
harlequin_info = HarlequinDebugInfo(
|
|
980
|
+
active_profile_config=active_profile_config,
|
|
981
|
+
active_profile_name=active_profile_name,
|
|
982
|
+
all_keymaps=list(self.all_keymaps.keys()),
|
|
983
|
+
config=config,
|
|
984
|
+
config_path=config_path,
|
|
985
|
+
keymap_names=self.keymap_names,
|
|
986
|
+
theme=self.theme,
|
|
987
|
+
)
|
|
988
|
+
adapter_info = AdapterDebugInfo(
|
|
989
|
+
adapter_options=adapter_options,
|
|
990
|
+
adapter_type=adapter_type,
|
|
991
|
+
adapter_details=self.adapter.ADAPTER_DETAILS
|
|
992
|
+
if self.adapter.provides_details
|
|
993
|
+
else "No details were provided by adapter.",
|
|
994
|
+
adapter_driver_details=self.adapter.ADAPTER_DRIVER_DETAILS
|
|
995
|
+
if self.adapter.provides_driver_details
|
|
996
|
+
else "No details were provided by the database driver.",
|
|
997
|
+
)
|
|
998
|
+
self.push_screen(
|
|
999
|
+
DebugInfoScreen(
|
|
1000
|
+
harlequin_details=harlequin_info.parse_info(),
|
|
1001
|
+
adapter_details=adapter_info.parse_info(),
|
|
1002
|
+
id=SCREEN_ID,
|
|
1003
|
+
)
|
|
1004
|
+
)
|
|
1005
|
+
|
|
954
1006
|
def action_toggle_full_screen(self) -> None:
|
|
955
1007
|
self.full_screen = not self.full_screen
|
|
956
1008
|
|
|
@@ -418,7 +418,9 @@ HelpScreen {
|
|
|
418
418
|
padding: 0;
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
-
|
|
421
|
+
/* Shared Components */
|
|
422
|
+
|
|
423
|
+
#modal_outer {
|
|
422
424
|
border: round $border-color-focus;
|
|
423
425
|
background: $background;
|
|
424
426
|
margin: 2 4;
|
|
@@ -426,22 +428,22 @@ HelpScreen {
|
|
|
426
428
|
max-width: 88;
|
|
427
429
|
}
|
|
428
430
|
|
|
429
|
-
#
|
|
431
|
+
#modal_header {
|
|
430
432
|
dock: top;
|
|
431
433
|
margin: 0 0 1 0;
|
|
432
434
|
padding: 0 1;
|
|
433
435
|
}
|
|
434
436
|
|
|
435
|
-
#
|
|
437
|
+
#modal_inner {
|
|
436
438
|
border: round $border-color-nofocus;
|
|
437
439
|
padding: 0 0 0 0;
|
|
438
440
|
}
|
|
439
441
|
|
|
440
|
-
#
|
|
442
|
+
#modal_info {
|
|
441
443
|
padding: 0 0 0 0;
|
|
442
444
|
}
|
|
443
445
|
|
|
444
|
-
#
|
|
446
|
+
#modal_footer {
|
|
445
447
|
dock: bottom;
|
|
446
448
|
color: $text-muted;
|
|
447
449
|
margin: 1 0 0 0;
|
|
@@ -618,6 +620,12 @@ HistoryScreen .history-screen--error-label {
|
|
|
618
620
|
text-style: bold italic;
|
|
619
621
|
}
|
|
620
622
|
|
|
623
|
+
/* DEBUG INFO SCREEN */
|
|
624
|
+
|
|
625
|
+
DebugInfoScreen {
|
|
626
|
+
align: center middle;
|
|
627
|
+
padding: 0;
|
|
628
|
+
}
|
|
621
629
|
|
|
622
630
|
/* ConfirmModal */
|
|
623
631
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from harlequin.components.code_editor import CodeEditor, EditorCollection
|
|
2
2
|
from harlequin.components.data_catalog import DataCatalog, HarlequinTree
|
|
3
|
+
from harlequin.components.debug_info import DebugInfoScreen
|
|
3
4
|
from harlequin.components.error_modal import ErrorModal
|
|
4
5
|
from harlequin.components.export_screen import ExportScreen, export_callback
|
|
5
6
|
from harlequin.components.help_screen import HelpScreen
|
|
@@ -15,6 +16,7 @@ __all__ = [
|
|
|
15
16
|
"export_callback",
|
|
16
17
|
"HelpScreen",
|
|
17
18
|
"ResultsTable",
|
|
19
|
+
"DebugInfoScreen",
|
|
18
20
|
"ResultsViewer",
|
|
19
21
|
"RunQueryBar",
|
|
20
22
|
"DataCatalog",
|