sqlit-tui 0.4.2__tar.gz → 1.0.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.
Files changed (238) hide show
  1. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/.github/workflows/ci.yml +78 -0
  2. sqlit_tui-1.0.0/.github/workflows/release.yml +146 -0
  3. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/.gitignore +20 -0
  4. sqlit_tui-1.0.0/.pre-commit-config.yaml +10 -0
  5. sqlit_tui-1.0.0/.sqlit-config/settings.json +4 -0
  6. sqlit_tui-1.0.0/PKG-INFO +282 -0
  7. sqlit_tui-1.0.0/README.md +211 -0
  8. sqlit_tui-1.0.0/aur/.SRCINFO +25 -0
  9. sqlit_tui-1.0.0/aur/PKGBUILD +38 -0
  10. sqlit_tui-1.0.0/demos/demo-connect.gif +0 -0
  11. sqlit_tui-1.0.0/demos/demo-history.gif +0 -0
  12. sqlit_tui-1.0.0/demos/demo-providers.gif +0 -0
  13. sqlit_tui-1.0.0/demos/demo-query.gif +0 -0
  14. sqlit_tui-1.0.0/demos/demo-sqlite.gif +0 -0
  15. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/docker-compose.test.yml +75 -0
  16. sqlit_tui-1.0.0/mypy-errors.txt +208 -0
  17. sqlit_tui-1.0.0/mypy-summary.md +68 -0
  18. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/pyproject.toml +76 -3
  19. sqlit_tui-1.0.0/pyrightconfig.json +10 -0
  20. sqlit_tui-1.0.0/settings.template.json +314 -0
  21. sqlit_tui-1.0.0/sqlit/__init__.py +59 -0
  22. sqlit_tui-1.0.0/sqlit/app.py +719 -0
  23. sqlit_tui-1.0.0/sqlit/cli.py +310 -0
  24. sqlit_tui-1.0.0/sqlit/cli_helpers.py +171 -0
  25. sqlit_tui-1.0.0/sqlit/commands.py +432 -0
  26. sqlit_tui-1.0.0/sqlit/config.py +247 -0
  27. sqlit_tui-1.0.0/sqlit/db/__init__.py +107 -0
  28. sqlit_tui-1.0.0/sqlit/db/adapters/__init__.py +72 -0
  29. sqlit_tui-1.0.0/sqlit/db/adapters/base.py +483 -0
  30. sqlit_tui-1.0.0/sqlit/db/adapters/cockroachdb.py +70 -0
  31. sqlit_tui-1.0.0/sqlit/db/adapters/d1.py +213 -0
  32. sqlit_tui-1.0.0/sqlit/db/adapters/duckdb.py +156 -0
  33. sqlit_tui-1.0.0/sqlit/db/adapters/mariadb.py +143 -0
  34. sqlit_tui-1.0.0/sqlit/db/adapters/mssql.py +236 -0
  35. sqlit_tui-1.0.0/sqlit/db/adapters/mysql.py +52 -0
  36. sqlit_tui-1.0.0/sqlit/db/adapters/oracle.py +149 -0
  37. sqlit_tui-1.0.0/sqlit/db/adapters/postgresql.py +71 -0
  38. sqlit_tui-1.0.0/sqlit/db/adapters/sqlite.py +110 -0
  39. sqlit_tui-1.0.0/sqlit/db/adapters/supabase.py +30 -0
  40. sqlit_tui-1.0.0/sqlit/db/adapters/turso.py +126 -0
  41. sqlit_tui-1.0.0/sqlit/db/exceptions.py +20 -0
  42. sqlit_tui-1.0.0/sqlit/db/providers.py +143 -0
  43. sqlit_tui-1.0.0/sqlit/db/schema.py +562 -0
  44. sqlit_tui-1.0.0/sqlit/db/tunnel.py +58 -0
  45. sqlit_tui-1.0.0/sqlit/drivers.py +273 -0
  46. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/sqlit/fields.py +63 -18
  47. sqlit_tui-1.0.0/sqlit/install_strategy.py +188 -0
  48. sqlit_tui-1.0.0/sqlit/keymap.py +158 -0
  49. sqlit_tui-1.0.0/sqlit/mock_settings.py +275 -0
  50. sqlit_tui-1.0.0/sqlit/mocks.py +593 -0
  51. sqlit_tui-1.0.0/sqlit/services/__init__.py +66 -0
  52. sqlit_tui-1.0.0/sqlit/services/cancellable.py +180 -0
  53. sqlit_tui-1.0.0/sqlit/services/credentials.py +369 -0
  54. sqlit_tui-1.0.0/sqlit/services/executor.py +132 -0
  55. sqlit_tui-1.0.0/sqlit/services/installer.py +182 -0
  56. sqlit_tui-1.0.0/sqlit/services/protocols.py +177 -0
  57. sqlit_tui-1.0.0/sqlit/services/query.py +126 -0
  58. sqlit_tui-1.0.0/sqlit/services/session.py +211 -0
  59. sqlit_tui-1.0.0/sqlit/state_machine.py +948 -0
  60. sqlit_tui-1.0.0/sqlit/stores/__init__.py +17 -0
  61. sqlit_tui-1.0.0/sqlit/stores/base.py +86 -0
  62. sqlit_tui-1.0.0/sqlit/stores/connections.py +231 -0
  63. sqlit_tui-1.0.0/sqlit/stores/history.py +180 -0
  64. sqlit_tui-1.0.0/sqlit/stores/settings.py +113 -0
  65. sqlit_tui-1.0.0/sqlit/terminal.py +76 -0
  66. sqlit_tui-1.0.0/sqlit/ui/__init__.py +39 -0
  67. sqlit_tui-1.0.0/sqlit/ui/mixins/__init__.py +19 -0
  68. sqlit_tui-1.0.0/sqlit/ui/mixins/autocomplete.py +431 -0
  69. sqlit_tui-1.0.0/sqlit/ui/mixins/connection.py +478 -0
  70. sqlit_tui-1.0.0/sqlit/ui/mixins/protocols.py +94 -0
  71. sqlit_tui-1.0.0/sqlit/ui/mixins/query.py +350 -0
  72. sqlit_tui-1.0.0/sqlit/ui/mixins/results.py +253 -0
  73. sqlit_tui-1.0.0/sqlit/ui/mixins/tree.py +476 -0
  74. sqlit_tui-1.0.0/sqlit/ui/mixins/tree_filter.py +313 -0
  75. sqlit_tui-1.0.0/sqlit/ui/mixins/ui_navigation.py +533 -0
  76. sqlit_tui-1.0.0/sqlit/ui/protocols.py +525 -0
  77. sqlit_tui-1.0.0/sqlit/ui/screens/__init__.py +60 -0
  78. sqlit_tui-1.0.0/sqlit/ui/screens/confirm.py +107 -0
  79. sqlit_tui-1.0.0/sqlit/ui/screens/connection.py +1658 -0
  80. sqlit_tui-1.0.0/sqlit/ui/screens/connection_picker.py +161 -0
  81. sqlit_tui-1.0.0/sqlit/ui/screens/driver_setup.py +156 -0
  82. sqlit_tui-1.0.0/sqlit/ui/screens/error.py +65 -0
  83. sqlit_tui-1.0.0/sqlit/ui/screens/help.py +55 -0
  84. sqlit_tui-1.0.0/sqlit/ui/screens/leader_menu.py +103 -0
  85. sqlit_tui-1.0.0/sqlit/ui/screens/loading.py +58 -0
  86. sqlit_tui-1.0.0/sqlit/ui/screens/message.py +75 -0
  87. sqlit_tui-1.0.0/sqlit/ui/screens/package_setup.py +110 -0
  88. sqlit_tui-1.0.0/sqlit/ui/screens/password_input.py +148 -0
  89. sqlit_tui-1.0.0/sqlit/ui/screens/query_history.py +170 -0
  90. sqlit_tui-1.0.0/sqlit/ui/screens/theme.py +115 -0
  91. sqlit_tui-1.0.0/sqlit/ui/screens/value_view.py +94 -0
  92. sqlit_tui-1.0.0/sqlit/ui/tree_nodes.py +97 -0
  93. sqlit_tui-1.0.0/sqlit/utils.py +76 -0
  94. sqlit_tui-1.0.0/sqlit/validation.py +98 -0
  95. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/sqlit/widgets.py +137 -23
  96. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/tests/conftest.py +393 -179
  97. sqlit_tui-1.0.0/tests/fixtures/99-fix-sshd-config.sh +6 -0
  98. sqlit_tui-1.0.0/tests/fixtures/d1/Dockerfile +13 -0
  99. sqlit_tui-1.0.0/tests/fixtures/d1/index.js +72 -0
  100. sqlit_tui-1.0.0/tests/fixtures/d1/wrangler.toml +10 -0
  101. sqlit_tui-1.0.0/tests/fixtures/sshd_config +29 -0
  102. sqlit_tui-1.0.0/tests/integration/drivers/README.md +36 -0
  103. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/.gitkeep +0 -0
  104. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-01-connection.png +0 -0
  105. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-01-connection.svg +224 -0
  106. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-02-advanced.png +0 -0
  107. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-02-advanced.svg +222 -0
  108. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-03-driver-setup-empty.png +0 -0
  109. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-03-driver-setup-empty.svg +230 -0
  110. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-04-install-message.png +0 -0
  111. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-04-install-message.svg +224 -0
  112. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-05-back-to-connection.png +0 -0
  113. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-05-back-to-connection.svg +227 -0
  114. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-05-back-to-setup.svg +231 -0
  115. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-06-back-to-connection.svg +224 -0
  116. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-06-driver-setup-installed.png +0 -0
  117. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-06-driver-setup-installed.svg +225 -0
  118. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-07-driver-selected.png +0 -0
  119. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/mssql-07-driver-selected.svg +227 -0
  120. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-01-advanced.png +0 -0
  121. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-01-advanced.svg +224 -0
  122. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-02-driver-setup-empty.png +0 -0
  123. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-02-driver-setup-empty.svg +231 -0
  124. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-03-install-message-terminal-found.png +0 -0
  125. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-03-install-message-terminal-found.svg +224 -0
  126. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-04-back-to-connection.png +0 -0
  127. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-04-back-to-connection.svg +224 -0
  128. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-06-driver-setup-installed.png +0 -0
  129. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-06-driver-setup-installed.svg +225 -0
  130. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-07-driver-selected.png +0 -0
  131. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-07-driver-selected.svg +227 -0
  132. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-07-driver-setup-installed.png +0 -0
  133. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-07-driver-setup-installed.svg +225 -0
  134. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-08-driver-selected.png +0 -0
  135. sqlit_tui-1.0.0/tests/integration/drivers/artifacts/terminal-found/mssql-08-driver-selected.svg +224 -0
  136. sqlit_tui-1.0.0/tests/integration/drivers/docker-compose.ui.yml +10 -0
  137. sqlit_tui-1.0.0/tests/integration/drivers/dockerfiles/alpine.Dockerfile +33 -0
  138. sqlit_tui-1.0.0/tests/integration/drivers/dockerfiles/arch.Dockerfile +32 -0
  139. sqlit_tui-1.0.0/tests/integration/drivers/dockerfiles/debian.Dockerfile +27 -0
  140. sqlit_tui-1.0.0/tests/integration/drivers/dockerfiles/fedora.Dockerfile +25 -0
  141. sqlit_tui-1.0.0/tests/integration/drivers/dockerfiles/opensuse.Dockerfile +25 -0
  142. sqlit_tui-1.0.0/tests/integration/drivers/dockerfiles/rocky.Dockerfile +26 -0
  143. sqlit_tui-1.0.0/tests/integration/drivers/dockerfiles/ubuntu.Dockerfile +27 -0
  144. sqlit_tui-1.0.0/tests/integration/drivers/dockerfiles/ui.Dockerfile +14 -0
  145. sqlit_tui-1.0.0/tests/integration/drivers/run_tests.sh +49 -0
  146. sqlit_tui-1.0.0/tests/integration/drivers/run_ui_tests.sh +6 -0
  147. sqlit_tui-1.0.0/tests/integration/drivers/test_driver_install.py +215 -0
  148. sqlit_tui-1.0.0/tests/integration/drivers/test_driver_setup_ui_flow.py +176 -0
  149. sqlit_tui-1.0.0/tests/integration/python_packages/README.md +26 -0
  150. sqlit_tui-1.0.0/tests/integration/python_packages/dockerfiles/debian.Dockerfile +13 -0
  151. sqlit_tui-1.0.0/tests/integration/python_packages/run_tests.sh +6 -0
  152. sqlit_tui-1.0.0/tests/integration/python_packages/test_package_install_flow.py +179 -0
  153. sqlit_tui-1.0.0/tests/integration/test_database_browsing_flow.py +496 -0
  154. sqlit_tui-1.0.0/tests/test_cockroachdb.py +104 -0
  155. sqlit_tui-1.0.0/tests/test_credentials_service.py +558 -0
  156. sqlit_tui-1.0.0/tests/test_d1.py +56 -0
  157. sqlit_tui-1.0.0/tests/test_database_base.py +409 -0
  158. sqlit_tui-1.0.0/tests/test_duckdb.py +129 -0
  159. sqlit_tui-1.0.0/tests/test_install_strategy.py +41 -0
  160. sqlit_tui-1.0.0/tests/test_installer_cancel.py +66 -0
  161. sqlit_tui-1.0.0/tests/test_mariadb.py +94 -0
  162. sqlit_tui-1.0.0/tests/test_mocks.py +166 -0
  163. sqlit_tui-1.0.0/tests/test_mssql.py +103 -0
  164. sqlit_tui-1.0.0/tests/test_mysql.py +94 -0
  165. sqlit_tui-1.0.0/tests/test_oracle.py +109 -0
  166. sqlit_tui-1.0.0/tests/test_password_prompts.py +444 -0
  167. sqlit_tui-1.0.0/tests/test_postgresql.py +104 -0
  168. sqlit_tui-1.0.0/tests/test_schema_capabilities.py +61 -0
  169. sqlit_tui-1.0.0/tests/test_sqlite.py +126 -0
  170. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/tests/test_ssh.py +96 -46
  171. sqlit_tui-1.0.0/tests/test_turso.py +123 -0
  172. sqlit_tui-1.0.0/tests/test_validation.py +144 -0
  173. sqlit_tui-1.0.0/tests/ui/__init__.py +1 -0
  174. sqlit_tui-1.0.0/tests/ui/conftest.py +123 -0
  175. sqlit_tui-1.0.0/tests/ui/explorer/__init__.py +1 -0
  176. sqlit_tui-1.0.0/tests/ui/explorer/test_markup_escaping.py +392 -0
  177. sqlit_tui-1.0.0/tests/ui/explorer/test_tree_expansion.py +230 -0
  178. sqlit_tui-1.0.0/tests/ui/keybindings/__init__.py +1 -0
  179. sqlit_tui-1.0.0/tests/ui/keybindings/conftest.py +37 -0
  180. sqlit_tui-1.0.0/tests/ui/keybindings/test_contextual.py +94 -0
  181. sqlit_tui-1.0.0/tests/ui/keybindings/test_dialogs.py +287 -0
  182. sqlit_tui-1.0.0/tests/ui/keybindings/test_insert_mode.py +81 -0
  183. sqlit_tui-1.0.0/tests/ui/keybindings/test_keymap_provider.py +86 -0
  184. sqlit_tui-1.0.0/tests/ui/keybindings/test_leader.py +65 -0
  185. sqlit_tui-1.0.0/tests/ui/keybindings/test_state_machine.py +104 -0
  186. sqlit_tui-1.0.0/tests/ui/mocks.py +257 -0
  187. sqlit_tui-1.0.0/tests/ui/snapshots/01_default_sqlite_screen.svg +203 -0
  188. sqlit_tui-1.0.0/tests/ui/snapshots/02_edit_mode_postgresql.svg +203 -0
  189. sqlit_tui-1.0.0/tests/ui/snapshots/03_before_cancel.svg +203 -0
  190. sqlit_tui-1.0.0/tests/ui/snapshots/04_empty_name_after_save_attempt.svg +204 -0
  191. sqlit_tui-1.0.0/tests/ui/snapshots/04_empty_name_before_save.svg +203 -0
  192. sqlit_tui-1.0.0/tests/ui/snapshots/05_after_switch_to_postgresql.svg +204 -0
  193. sqlit_tui-1.0.0/tests/ui/snapshots/05_before_switch_to_postgresql.svg +203 -0
  194. sqlit_tui-1.0.0/tests/ui/snapshots/06_sqlite_file_path_field.svg +203 -0
  195. sqlit_tui-1.0.0/tests/ui/snapshots/07_sqlite_filled_form.svg +203 -0
  196. sqlit_tui-1.0.0/tests/ui/snapshots/08_postgresql_after_switch.svg +205 -0
  197. sqlit_tui-1.0.0/tests/ui/snapshots/08_postgresql_filled_form.svg +203 -0
  198. sqlit_tui-1.0.0/tests/ui/snapshots/09_duplicate_name_validation.svg +203 -0
  199. sqlit_tui-1.0.0/tests/ui/snapshots/10_after_test_connection.svg +204 -0
  200. sqlit_tui-1.0.0/tests/ui/snapshots/10_before_test_connection.svg +203 -0
  201. sqlit_tui-1.0.0/tests/ui/snapshots/11_navigation_after_tab.svg +203 -0
  202. sqlit_tui-1.0.0/tests/ui/snapshots/11_navigation_initial_focus.svg +203 -0
  203. sqlit_tui-1.0.0/tests/ui/snapshots/12_navigation_after_shift_tab.svg +203 -0
  204. sqlit_tui-1.0.0/tests/ui/snapshots/12_navigation_after_two_tabs.svg +204 -0
  205. sqlit_tui-1.0.0/tests/ui/snapshots/13_ssh_fields_hidden.svg +204 -0
  206. sqlit_tui-1.0.0/tests/ui/test_connect_action.py +85 -0
  207. sqlit_tui-1.0.0/tests/ui/test_connection_screen.py +279 -0
  208. sqlit_tui-1.0.0/tests/ui/test_explorer_toggle.py +121 -0
  209. sqlit_tui-1.0.0/tests/ui/test_password_input.py +392 -0
  210. sqlit_tui-1.0.0/tests/ui/test_query_history.py +161 -0
  211. sqlit_tui-1.0.0/tests/ui/test_tree_schema_grouping.py +413 -0
  212. sqlit_tui-1.0.0/uv.lock +1014 -0
  213. sqlit_tui-0.4.2/.github/workflows/release.yml +0 -64
  214. sqlit_tui-0.4.2/PKG-INFO +0 -166
  215. sqlit_tui-0.4.2/README.md +0 -129
  216. sqlit_tui-0.4.2/demo-connect.gif +0 -0
  217. sqlit_tui-0.4.2/demo-history.gif +0 -0
  218. sqlit_tui-0.4.2/demo-providers.gif +0 -0
  219. sqlit_tui-0.4.2/demo-query.gif +0 -0
  220. sqlit_tui-0.4.2/sqlit/__init__.py +0 -15
  221. sqlit_tui-0.4.2/sqlit/adapters.py +0 -1312
  222. sqlit_tui-0.4.2/sqlit/app.py +0 -1887
  223. sqlit_tui-0.4.2/sqlit/cli.py +0 -150
  224. sqlit_tui-0.4.2/sqlit/commands.py +0 -334
  225. sqlit_tui-0.4.2/sqlit/config.py +0 -278
  226. sqlit_tui-0.4.2/sqlit/drivers.py +0 -177
  227. sqlit_tui-0.4.2/sqlit/screens.py +0 -1765
  228. sqlit_tui-0.4.2/tests/test_cockroachdb.py +0 -188
  229. sqlit_tui-0.4.2/tests/test_duckdb.py +0 -213
  230. sqlit_tui-0.4.2/tests/test_mariadb.py +0 -186
  231. sqlit_tui-0.4.2/tests/test_mssql.py +0 -186
  232. sqlit_tui-0.4.2/tests/test_mysql.py +0 -186
  233. sqlit_tui-0.4.2/tests/test_oracle.py +0 -188
  234. sqlit_tui-0.4.2/tests/test_postgresql.py +0 -186
  235. sqlit_tui-0.4.2/tests/test_sqlite.py +0 -204
  236. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/CONTRIBUTING.md +0 -0
  237. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/LICENSE +0 -0
  238. {sqlit_tui-0.4.2 → sqlit_tui-1.0.0}/tests/__init__.py +0 -0
@@ -34,6 +34,39 @@ jobs:
34
34
  run: |
35
35
  python -c "from sqlit.cli import main; print('CLI import OK')"
36
36
 
37
+ test-unit:
38
+ runs-on: ubuntu-latest
39
+ strategy:
40
+ matrix:
41
+ python-version: ["3.10", "3.12"]
42
+
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+
46
+ - name: Set up Python ${{ matrix.python-version }}
47
+ uses: actions/setup-python@v5
48
+ with:
49
+ python-version: ${{ matrix.python-version }}
50
+
51
+ - name: Install dependencies
52
+ run: |
53
+ python -m pip install --upgrade pip
54
+ pip install -e ".[test]"
55
+
56
+ - name: Run unit tests
57
+ run: |
58
+ pytest tests/ -v --timeout=60 \
59
+ --ignore=tests/test_sqlite.py \
60
+ --ignore=tests/test_mssql.py \
61
+ --ignore=tests/test_postgresql.py \
62
+ --ignore=tests/test_mysql.py \
63
+ --ignore=tests/test_oracle.py \
64
+ --ignore=tests/test_mariadb.py \
65
+ --ignore=tests/test_duckdb.py \
66
+ --ignore=tests/test_cockroachdb.py \
67
+ --ignore=tests/test_turso.py \
68
+ --ignore=tests/test_ssh.py
69
+
37
70
  test-sqlite:
38
71
  runs-on: ubuntu-latest
39
72
  strategy:
@@ -448,3 +481,48 @@ jobs:
448
481
  docker stop sshserver postgres || true
449
482
  docker rm sshserver postgres || true
450
483
  docker network rm ssh-test-net || true
484
+
485
+ test-turso:
486
+ runs-on: ubuntu-latest
487
+ needs: build
488
+
489
+ steps:
490
+ - uses: actions/checkout@v4
491
+
492
+ - name: Set up Python 3.12
493
+ uses: actions/setup-python@v5
494
+ with:
495
+ python-version: "3.12"
496
+
497
+ - name: Install dependencies
498
+ run: |
499
+ python -m pip install --upgrade pip
500
+ pip install -e ".[test]"
501
+ pip install libsql-client
502
+
503
+ - name: Start Turso (libsql-server)
504
+ run: |
505
+ docker run -d --name turso \
506
+ -p 8080:8080 \
507
+ ghcr.io/tursodatabase/libsql-server:latest
508
+ # Wait for Turso to be ready
509
+ for i in {1..30}; do
510
+ if curl -sf http://localhost:8080/health > /dev/null 2>&1; then
511
+ echo "Turso is ready"
512
+ break
513
+ fi
514
+ echo "Waiting for Turso... ($i/30)"
515
+ sleep 2
516
+ done
517
+
518
+ - name: Run Turso integration tests
519
+ env:
520
+ TURSO_URL: http://localhost:8080
521
+ run: |
522
+ pytest tests/test_turso.py -v --timeout=120
523
+
524
+ - name: Cleanup
525
+ if: always()
526
+ run: |
527
+ docker stop turso || true
528
+ docker rm turso || true
@@ -0,0 +1,146 @@
1
+ name: Release and Publish
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+ workflow_dispatch:
8
+ inputs:
9
+ version:
10
+ description: 'Version to release (e.g., 0.4.2)'
11
+ required: true
12
+
13
+ jobs:
14
+ release:
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: write
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Extract version from tag
22
+ id: version
23
+ run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
24
+
25
+ - name: Create GitHub Release
26
+ uses: softprops/action-gh-release@v1
27
+ with:
28
+ name: ${{ steps.version.outputs.VERSION }}
29
+ generate_release_notes: true
30
+ draft: false
31
+ prerelease: false
32
+
33
+ build:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+
38
+ - name: Extract version from tag
39
+ id: version
40
+ run: |
41
+ if [ -n "${{ github.event.inputs.version }}" ]; then
42
+ echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
43
+ else
44
+ # Strip the 'v' prefix from the tag
45
+ echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
46
+ fi
47
+
48
+ - name: Set up Python
49
+ uses: actions/setup-python@v5
50
+ with:
51
+ python-version: "3.12"
52
+
53
+ - name: Update version in pyproject.toml
54
+ run: |
55
+ VERSION=${{ steps.version.outputs.VERSION }}
56
+ echo "Setting version to $VERSION"
57
+ sed -i "s/^version = .*/version = \"$VERSION\"/" pyproject.toml
58
+ echo "Updated pyproject.toml:"
59
+ grep "^version" pyproject.toml
60
+
61
+ - name: Install build tools
62
+ run: python -m pip install --upgrade build
63
+
64
+ - name: Build package
65
+ run: python -m build
66
+
67
+ - name: Upload dist artifacts
68
+ uses: actions/upload-artifact@v4
69
+ with:
70
+ name: dist
71
+ path: dist/
72
+
73
+ publish:
74
+ needs: build
75
+ runs-on: ubuntu-latest
76
+ environment: pypi
77
+ permissions:
78
+ id-token: write
79
+ steps:
80
+ - name: Download dist artifacts
81
+ uses: actions/download-artifact@v4
82
+ with:
83
+ name: dist
84
+ path: dist/
85
+
86
+ - name: Publish to PyPI
87
+ uses: pypa/gh-action-pypi-publish@release/v1
88
+
89
+ aur:
90
+ needs: publish
91
+ runs-on: ubuntu-latest
92
+ steps:
93
+ - uses: actions/checkout@v4
94
+
95
+ - name: Extract version
96
+ id: version
97
+ run: |
98
+ if [ -n "${{ github.event.inputs.version }}" ]; then
99
+ echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
100
+ else
101
+ echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
102
+ fi
103
+
104
+ - name: Setup SSH for AUR
105
+ run: |
106
+ mkdir -p ~/.ssh
107
+ echo "${{ secrets.AUR_SSH_KEY }}" > ~/.ssh/aur
108
+ chmod 600 ~/.ssh/aur
109
+ echo "Host aur.archlinux.org" >> ~/.ssh/config
110
+ echo " IdentityFile ~/.ssh/aur" >> ~/.ssh/config
111
+ echo " User aur" >> ~/.ssh/config
112
+ ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
113
+
114
+ - name: Clone AUR repo
115
+ run: git clone ssh://aur@aur.archlinux.org/python-sqlit-tui.git aur-repo
116
+
117
+ - name: Update PKGBUILD
118
+ run: |
119
+ cd aur-repo
120
+ VERSION=${{ steps.version.outputs.VERSION }}
121
+
122
+ # Wait for PyPI to have the package available
123
+ sleep 30
124
+
125
+ # Download new tarball and get checksum
126
+ curl -sL "https://files.pythonhosted.org/packages/source/s/sqlit-tui/sqlit_tui-${VERSION}.tar.gz" -o /tmp/pkg.tar.gz
127
+ CHECKSUM=$(sha256sum /tmp/pkg.tar.gz | cut -d' ' -f1)
128
+
129
+ # Update version and checksum in PKGBUILD
130
+ sed -i "s/^pkgver=.*/pkgver=${VERSION}/" PKGBUILD
131
+ sed -i "s/^pkgrel=.*/pkgrel=1/" PKGBUILD
132
+ sed -i "s/^sha256sums=.*/sha256sums=('${CHECKSUM}')/" PKGBUILD
133
+
134
+ # Update .SRCINFO
135
+ sed -i "s/pkgver = .*/pkgver = ${VERSION}/" .SRCINFO
136
+ sed -i "s/sqlit_tui-[0-9.]*/sqlit_tui-${VERSION}/g" .SRCINFO
137
+ sed -i "s/sha256sums = .*/sha256sums = ${CHECKSUM}/" .SRCINFO
138
+
139
+ - name: Push to AUR
140
+ run: |
141
+ cd aur-repo
142
+ git config user.email "peter.w.adams96@gmail.com"
143
+ git config user.name "Peter"
144
+ git add PKGBUILD .SRCINFO
145
+ git diff --staged --quiet || git commit -m "Update to v${{ steps.version.outputs.VERSION }}"
146
+ git push
@@ -19,6 +19,11 @@ venv/
19
19
  *.swp
20
20
  *.swo
21
21
 
22
+ # Local caches
23
+ .cache/
24
+ .ruff_cache/
25
+ .sqlit/
26
+
22
27
  # OS
23
28
  .DS_Store
24
29
 
@@ -26,3 +31,18 @@ venv/
26
31
  docker-compose.yml
27
32
  init.sql
28
33
  *.tape
34
+ .tmp/
35
+ demos/drafts/
36
+
37
+ # Database files
38
+ *.db
39
+
40
+ # AUR build artifacts
41
+ aur/*.tar.gz
42
+ aur/src/
43
+ aur/pkg/
44
+ aur/*.pkg.tar.*
45
+ sqlit-notifications/
46
+
47
+ # Integration test artifacts
48
+ tests/integration/python_packages/artifacts/
@@ -0,0 +1,10 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-toml
9
+ - id: check-added-large-files
10
+ - id: check-merge-conflict
@@ -0,0 +1,4 @@
1
+ {
2
+ "theme": "tokyo-night",
3
+ "expanded_nodes": []
4
+ }
@@ -0,0 +1,282 @@
1
+ Metadata-Version: 2.4
2
+ Name: sqlit-tui
3
+ Version: 1.0.0
4
+ Summary: A terminal UI for SQL Server, PostgreSQL, MySQL, SQLite, and Oracle
5
+ Project-URL: Homepage, https://github.com/Maxteabag/sqlit
6
+ Project-URL: Repository, https://github.com/Maxteabag/sqlit
7
+ Project-URL: Issues, https://github.com/Maxteabag/sqlit/issues
8
+ Author: Peter
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: database,mssql,mysql,oracle,postgresql,server,sql,sqlite,terminal,tui
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Database
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: keyring>=24.0.0
25
+ Requires-Dist: paramiko<4.0.0,>=2.0.0
26
+ Requires-Dist: pyperclip>=1.8.2
27
+ Requires-Dist: sshtunnel>=0.4.0
28
+ Requires-Dist: textual[syntax]>=6.10.0
29
+ Provides-Extra: all
30
+ Requires-Dist: duckdb>=0.9.0; extra == 'all'
31
+ Requires-Dist: libsql-client>=0.1.0; extra == 'all'
32
+ Requires-Dist: mariadb>=1.1.0; extra == 'all'
33
+ Requires-Dist: mysql-connector-python>=8.0.0; extra == 'all'
34
+ Requires-Dist: oracledb>=2.0.0; extra == 'all'
35
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == 'all'
36
+ Requires-Dist: pyodbc>=5.0.0; extra == 'all'
37
+ Requires-Dist: requests>=2.0.0; extra == 'all'
38
+ Provides-Extra: cockroachdb
39
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == 'cockroachdb'
40
+ Provides-Extra: d1
41
+ Requires-Dist: requests>=2.0.0; extra == 'd1'
42
+ Provides-Extra: dev
43
+ Requires-Dist: build; extra == 'dev'
44
+ Requires-Dist: mypy>=1.0; extra == 'dev'
45
+ Requires-Dist: pre-commit>=3.0; extra == 'dev'
46
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
47
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
48
+ Requires-Dist: pytest-timeout>=2.0; extra == 'dev'
49
+ Requires-Dist: pytest>=7.0; extra == 'dev'
50
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
51
+ Provides-Extra: duckdb
52
+ Requires-Dist: duckdb>=0.9.0; extra == 'duckdb'
53
+ Provides-Extra: mariadb
54
+ Requires-Dist: mariadb>=1.1.0; extra == 'mariadb'
55
+ Provides-Extra: mssql
56
+ Requires-Dist: pyodbc>=5.0.0; extra == 'mssql'
57
+ Provides-Extra: mysql
58
+ Requires-Dist: mysql-connector-python>=8.0.0; extra == 'mysql'
59
+ Provides-Extra: oracle
60
+ Requires-Dist: oracledb>=2.0.0; extra == 'oracle'
61
+ Provides-Extra: postgres
62
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == 'postgres'
63
+ Provides-Extra: test
64
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
65
+ Requires-Dist: pytest-cov>=4.0; extra == 'test'
66
+ Requires-Dist: pytest-timeout>=2.0; extra == 'test'
67
+ Requires-Dist: pytest>=7.0; extra == 'test'
68
+ Provides-Extra: turso
69
+ Requires-Dist: libsql-client>=0.1.0; extra == 'turso'
70
+ Description-Content-Type: text/markdown
71
+
72
+ # sqlit
73
+
74
+ **The lazygit of SQL databases.** Connect to Postgres, MySQL, SQL Server, SQLite, Supabase, Turso, and more from your terminal in seconds.
75
+
76
+ A lightweight TUI for people who just want to run some queries fast.
77
+
78
+ ![Python](https://img.shields.io/badge/python-3.10+-blue.svg)
79
+ ![License](https://img.shields.io/badge/license-MIT-green.svg)
80
+
81
+ ### Multi-database Support
82
+ ![Database Providers](demos/demo-providers.gif)
83
+
84
+ ### Query History
85
+ ![Query History](demos/demo-history.gif)
86
+
87
+
88
+ ## Features
89
+
90
+ - **Connection manager UI** - Save connections, switch between databases without CLI args
91
+ - **Just run `sqlit`** - No CLI config needed, pick a connection and go
92
+ - **Multi-database out of the box** - SQL Server, PostgreSQL, MySQL, SQLite, MariaDB, Oracle, DuckDB, CockroachDB, Supabase, Turso - no adapters to install
93
+ - **SSH tunnels built-in** - Connect to remote databases securely with password or key auth
94
+ - **Vim-style editing** - Modal editing for terminal purists
95
+ - **Query history** - Automatically saves queries per connection, searchable and sortable
96
+ - Context-aware help (no need to memorize keybindings)
97
+ - Browse databases, tables, views, and stored procedures
98
+ - SQL autocomplete for tables, columns, and procedures
99
+ - Multiple auth methods (Windows, SQL Server, Entra ID)
100
+ - CLI mode for scripting and AI agents
101
+ - Themes (Tokyo Night, Nord, and more)
102
+ - Auto-detects and installs ODBC drivers (SQL Server)
103
+
104
+
105
+ ## Motivation
106
+ I usually do my work in the terminal, but I found myself either having to boot up massively bloated GUI's like SSMS or Vscode for the simple task of merely browsing my databases and doing some queries toward them. For the vast majority of my use cases, I never used any of the advanced features for inspection and debugging that SSMS and other feature-rich clients provide.
107
+
108
+ I had the unfortunate situation where doing queries became a pain-point due to the massive operation it is to open SSMS and it's lack of intuitive keyboard only navigation.
109
+
110
+ The problem got severely worse when I switched to Linux and had to rely on VS CODE's SQL extension to access my database. Something was not right.
111
+
112
+ I tried to use some existing TUI's for SQL, but they were not intuitive for me and I missed the immediate ease of use that other TUI's such as Lazygit provides.
113
+
114
+ sqlit is a lightweight database TUI that is easy to use and beautiful to look at, just connect and query. It's for you that just wants to run queries toward your database without launching applications that eats your ram and takes time to load up. Sqlit supports SQL Server, PostgreSQL, MySQL, SQLite, MariaDB, Oracle, DuckDB, CockroachDB, Supabase, and Turso, and is designed to make it easy and enjoyable to access your data, not painful.
115
+
116
+
117
+ ## Installation
118
+
119
+ ### Method 1: `pipx` (Recommended)
120
+
121
+ 1. **Install pipx:** If you don't have pipx, you can install it with:
122
+ ```bash
123
+ python3 -m pip install --user pipx
124
+ python3 -m pipx ensurepath
125
+ ```
126
+
127
+ 2. **Install sqlit-tui:**
128
+ ```bash
129
+ pipx install sqlit-tui
130
+ ```
131
+
132
+ ### Method 2: `uv`
133
+
134
+ `uv` is a fast, modern installer. This also keeps things isolated and makes optional drivers easy.
135
+
136
+ ```bash
137
+ uv tool install sqlit-tui
138
+ ```
139
+
140
+ ### Method 3: `pip`
141
+
142
+ ```bash
143
+ pip install "sqlit-tui"
144
+ ```
145
+
146
+ ## Usage
147
+
148
+ ```bash
149
+ sqlit
150
+ ```
151
+
152
+ The keybindings are shown at the bottom of the screen.
153
+
154
+ ### Try it without a database
155
+
156
+ Want to explore the UI without connecting to a real database? Run with mock data:
157
+
158
+ ```bash
159
+ sqlit --mock=sqlite-demo
160
+ ```
161
+
162
+ ### CLI
163
+
164
+ ```bash
165
+ # Run a query
166
+ sqlit query -c "MyConnection" -q "SELECT * FROM Users"
167
+
168
+ # Output as CSV or JSON
169
+ sqlit query -c "MyConnection" -q "SELECT * FROM Users" --format csv
170
+ sqlit query -c "MyConnection" -f "script.sql" --format json
171
+
172
+ # Create connections for different databases
173
+ sqlit connections add mssql --name "MySqlServer" --server "localhost" --auth-type sql
174
+ sqlit connections add postgresql --name "MyPostgres" --server "localhost" --username "user" --password "pass"
175
+ sqlit connections add mysql --name "MyMySQL" --server "localhost" --username "user" --password "pass"
176
+ sqlit connections add cockroachdb --name "MyCockroach" --server "localhost" --port "26257" --database "defaultdb" --username "root"
177
+ sqlit connections add sqlite --name "MyLocalDB" --file-path "/path/to/database.db"
178
+ sqlit connections add turso --name "MyTurso" --server "libsql://your-db.turso.io" --password "your-auth-token"
179
+
180
+ # Connect via SSH tunnel
181
+ sqlit connections add postgresql --name "RemoteDB" --server "db-host" --username "dbuser" --password "dbpass" \
182
+ --ssh-enabled --ssh-host "ssh.example.com" --ssh-username "sshuser" --ssh-auth-type password --ssh-password "sshpass"
183
+
184
+ # Temporary (not saved) connection
185
+ sqlit connect sqlite --file-path "/path/to/database.db"
186
+
187
+ # Provider-specific CLI help
188
+ sqlit connect -h
189
+ sqlit connect supabase -h
190
+ sqlit connections add -h
191
+ sqlit connections add supabase -h
192
+
193
+ # Manage connections
194
+ sqlit connections list
195
+ sqlit connections delete "MyConnection"
196
+ ```
197
+
198
+ ## Keybindings
199
+
200
+ | Key | Action |
201
+ |-----|--------|
202
+ | `i` | Enter INSERT mode |
203
+ | `Esc` | Back to NORMAL mode |
204
+ | `e` / `q` / `r` | Focus Explorer / Query / Results |
205
+ | `s` | SELECT TOP 100 from table |
206
+ | `h` | Query history |
207
+ | `d` | Clear query |
208
+ | `n` | New query (clear all) |
209
+ | `y` | Copy query (when query editor is focused) |
210
+ | `v` / `y` / `Y` / `a` | View cell / Copy cell / Copy row / Copy all |
211
+ | `Ctrl+Q` | Quit |
212
+ | `?` | Help |
213
+
214
+ ### Commands Menu (`<space>`)
215
+
216
+ | Key | Action |
217
+ |-----|--------|
218
+ | `<space>c` | Connect to database |
219
+ | `<space>x` | Disconnect |
220
+ | `<space>z` | Cancel running query |
221
+ | `<space>e` | Toggle Explorer |
222
+ | `<space>f` | Toggle Maximize |
223
+ | `<space>t` | Change theme |
224
+ | `<space>h` | Help |
225
+ | `<space>q` | Quit |
226
+
227
+ Autocomplete triggers automatically in INSERT mode. Use `Tab` to accept.
228
+
229
+ You can also receive autocompletion on columns by typing the table name and hitting "."
230
+
231
+ ## Configuration
232
+
233
+ Connections and settings are stored in `~/.sqlit/`.
234
+
235
+ ## FAQ
236
+
237
+ ### How are sensitive credentials stored?
238
+
239
+ Connection details are stored in `~/.sqlit/connections.json`, but passwords are stored in your OS keyring when available (macOS Keychain, Windows Credential Locker, Linux Secret Service).
240
+
241
+ If a keyring backend isn't available, `sqlit` will ask whether to store passwords as plaintext in `~/.sqlit/` (protected permissions). If you decline, you’ll be prompted when needed.
242
+
243
+ ### How does sqlit compare to Harlequin, Lazysql, etc.?
244
+
245
+ sqlit is inspired by [lazygit](https://github.com/jesseduffield/lazygit) - you can just jump in and there's no need for external documentation. The keybindings are shown at the bottom of the screen and the UI is designed to be intuitive without memorizing shortcuts.
246
+
247
+ Key differences:
248
+ - **No need for external documentation** - Sqlit embrace the "lazy" approach in that a user should be able to jump in and use it right away intuitively. There should be no setup instructions. If python packages are required for certain adapters, sqlit will help you install them as you need them.
249
+ - **No CLI config required** - Just run `sqlit` and pick a connection from the UI
250
+ - **Lightweight** - While Lazysql or Harlequin offer more features, I experienced that for the vast majority of cases, all I needed was a simple and fast way to connect and run queries. Sqlit is focused on doing a limited amount of things really well.
251
+
252
+ ## Inspiration
253
+
254
+ sqlit is built with [Textual](https://github.com/Textualize/textual) and inspired by:
255
+ - [lazygit](https://github.com/jesseduffield/lazygit) - Simple TUI for git
256
+ - [lazysql](https://github.com/jorgerojas26/lazysql) - Terminal-based SQL client with connection manager
257
+
258
+ ## Contributing
259
+
260
+ See `CONTRIBUTING.md` for development setup, testing, CI, and CockroachDB quickstart steps.
261
+
262
+ ### Driver Reference
263
+
264
+ Most of the time you can just run `sqlit` and connect. If a Python driver is missing, `sqlit` will show (and often run) the right install command for your environment.
265
+
266
+ | Database | Driver package | `pipx` | `pip` / venv |
267
+ | :--- | :--- | :--- | :--- |
268
+ | SQLite | *(built-in)* | *(built-in)* | *(built-in)* |
269
+ | PostgreSQL / CockroachDB / Supabase | `psycopg2-binary` | `pipx inject sqlit-tui psycopg2-binary` | `python -m pip install psycopg2-binary` |
270
+ | SQL Server | `pyodbc` | `pipx inject sqlit-tui pyodbc` | `python -m pip install pyodbc` |
271
+ | MySQL | `mysql-connector-python` | `pipx inject sqlit-tui mysql-connector-python` | `python -m pip install mysql-connector-python` |
272
+ | MariaDB | `mariadb` | `pipx inject sqlit-tui mariadb` | `python -m pip install mariadb` |
273
+ | Oracle | `oracledb` | `pipx inject sqlit-tui oracledb` | `python -m pip install oracledb` |
274
+ | DuckDB | `duckdb` | `pipx inject sqlit-tui duckdb` | `python -m pip install duckdb` |
275
+ | Turso | `libsql-client` | `pipx inject sqlit-tui libsql-client` | `python -m pip install libsql-client` |
276
+ | Cloudflare D1 | `requests` | `pipx inject sqlit-tui requests` | `python -m pip install requests` |
277
+
278
+ **Note:** SQL Server also requires the platform-specific ODBC driver. On your first connection attempt, `sqlit` can help you install it if it's missing.
279
+
280
+ ## License
281
+
282
+ MIT