Skip to content

Commit 94413ec

Browse files
authored
Docker (#24)
* Add docker discovery - improve connection loading - add direct connection module * Docker * Tests for docker * Make docker detection more robust * Robust indexing, fix search, add search to results, * UX bug fixes and mariadb warning * Oracle role - Omarchy - Fast data table - Result search - SSH optimizations - Connectionstring CLI support * Add query favorite feature and fix race conditions * Hide column header on Fast data table when no results * Update readme --------- Co-authored-by: Peter Adams <18162810+Maxteabag@users.noreply.github.com>
1 parent d044523 commit 94413ec

68 files changed

Lines changed: 10193 additions & 313 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -101,47 +101,48 @@ jobs:
101101
echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
102102
fi
103103
104-
- name: Setup SSH for AUR
104+
- name: Wait for PyPI and get checksum
105+
id: pypi
105106
run: |
106-
mkdir -p ~/.ssh
107-
# Decode base64-encoded SSH key (encode with: base64 -w 0 < ~/.ssh/aur_key)
108-
echo "${{ secrets.AUR_SSH_KEY }}" | base64 -d > ~/.ssh/aur
109-
chmod 600 ~/.ssh/aur
110-
echo "Host aur.archlinux.org" >> ~/.ssh/config
111-
echo " IdentityFile ~/.ssh/aur" >> ~/.ssh/config
112-
echo " User aur" >> ~/.ssh/config
113-
ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
114-
115-
- name: Clone AUR repo
116-
run: git clone ssh://aur@aur.archlinux.org/python-sqlit-tui.git aur-repo
107+
VERSION=${{ steps.version.outputs.VERSION }}
108+
URL="https://files.pythonhosted.org/packages/source/s/sqlit-tui/sqlit_tui-${VERSION}.tar.gz"
109+
110+
echo "Waiting for package to be available on PyPI..."
111+
for i in {1..20}; do
112+
HTTP_CODE=$(curl -sI -o /dev/null -w "%{http_code}" "$URL")
113+
if [ "$HTTP_CODE" = "200" ]; then
114+
echo "Package available on PyPI (attempt $i)"
115+
break
116+
fi
117+
echo "Waiting for PyPI... attempt $i (got HTTP $HTTP_CODE)"
118+
sleep 30
119+
done
120+
121+
# Download and compute checksum
122+
curl -sL "$URL" -o /tmp/pkg.tar.gz
123+
CHECKSUM=$(sha256sum /tmp/pkg.tar.gz | cut -d' ' -f1)
124+
echo "CHECKSUM=${CHECKSUM}" >> $GITHUB_OUTPUT
125+
echo "Checksum: ${CHECKSUM}"
117126
118127
- name: Update PKGBUILD
119128
run: |
120-
cd aur-repo
121129
VERSION=${{ steps.version.outputs.VERSION }}
130+
CHECKSUM=${{ steps.pypi.outputs.CHECKSUM }}
122131
123-
# Wait for PyPI to have the package available
124-
sleep 30
125-
126-
# Download new tarball and get checksum
127-
curl -sL "https://files.pythonhosted.org/packages/source/s/sqlit-tui/sqlit_tui-${VERSION}.tar.gz" -o /tmp/pkg.tar.gz
128-
CHECKSUM=$(sha256sum /tmp/pkg.tar.gz | cut -d' ' -f1)
129-
130-
# Update version and checksum in PKGBUILD
132+
cd aur
131133
sed -i "s/^pkgver=.*/pkgver=${VERSION}/" PKGBUILD
132134
sed -i "s/^pkgrel=.*/pkgrel=1/" PKGBUILD
133135
sed -i "s/^sha256sums=.*/sha256sums=('${CHECKSUM}')/" PKGBUILD
134136
135-
# Update .SRCINFO
136-
sed -i "s/pkgver = .*/pkgver = ${VERSION}/" .SRCINFO
137-
sed -i "s/sqlit_tui-[0-9.]*/sqlit_tui-${VERSION}/g" .SRCINFO
138-
sed -i "s/sha256sums = .*/sha256sums = ${CHECKSUM}/" .SRCINFO
137+
echo "Updated PKGBUILD:"
138+
cat PKGBUILD
139139
140-
- name: Push to AUR
141-
run: |
142-
cd aur-repo
143-
git config user.email "peter.w.adams96@gmail.com"
144-
git config user.name "Peter"
145-
git add PKGBUILD .SRCINFO
146-
git diff --staged --quiet || git commit -m "Update to v${{ steps.version.outputs.VERSION }}"
147-
git push
140+
- name: Publish to AUR
141+
uses: KSXGitHub/github-actions-deploy-aur@v3.0.1
142+
with:
143+
pkgname: python-sqlit-tui
144+
pkgbuild: ./aur/PKGBUILD
145+
commit_username: Peter
146+
commit_email: peter.w.adams96@gmail.com
147+
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
148+
commit_message: "Update to v${{ steps.version.outputs.VERSION }}"

README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,23 @@ A lightweight TUI for people who just want to run some queries fast.
1212

1313
### Query History
1414
![Query History](demos/demo-history.gif)
15+
**Filter results**
16+
![Filter results](demos/demo-filter/demo-filter.gif)
1517

1618

1719
## Features
1820

1921
- **Connection manager UI** - Save connections, switch between databases without CLI args
2022
- **Just run `sqlit`** - No CLI config needed, pick a connection and go
2123
- **Multi-database out of the box** - SQL Server, PostgreSQL, MySQL, SQLite, MariaDB, Oracle, DuckDB, CockroachDB, Supabase, Turso - no adapters to install
24+
- Connect directly to database docker container
2225
- **SSH tunnels built-in** - Connect to remote databases securely with password or key auth
2326
- **Vim-style editing** - Modal editing for terminal purists
2427
- **Query history** - Automatically saves queries per connection, searchable and sortable
28+
- Filter results
2529
- Context-aware help (no need to memorize keybindings)
2630
- Browse databases, tables, views, and stored procedures
31+
- Indexes, Triggers and Sequences
2732
- SQL autocomplete for tables, columns, and procedures
2833
- Multiple auth methods (Windows, SQL Server, Entra ID)
2934
- CLI mode for scripting and AI agents
@@ -103,6 +108,14 @@ sqlit connections add postgresql --name "RemoteDB" --server "db-host" --username
103108
# Temporary (not saved) connection
104109
sqlit connect sqlite --file-path "/path/to/database.db"
105110

111+
# Connect via URL - scheme determines database type (postgresql://, mysql://, sqlite://, etc.)
112+
sqlit postgresql://user:pass@localhost:5432/mydb
113+
sqlit mysql://root@localhost/testdb
114+
sqlit sqlite:///path/to/database.db
115+
116+
# Save a connection via URL
117+
sqlit connections add --url dbtype://user:pass@host/db --name "MyDB"
118+
106119
# Provider-specific CLI help
107120
sqlit connect -h
108121
sqlit connect supabase -h
@@ -208,6 +221,84 @@ SSH tunnel functionality requires additional dependencies. Install with the `ssh
208221

209222
If you try to create an SSH connection without these dependencies, sqlit will detect this and show you the exact command to install them for your environment.
210223

224+
### Vision
225+
226+
The core purpose of this application is to read Read&Write to a SQL database.
227+
The core elements to achieve this purpose is: CEQR:
228+
229+
- C: Connecting
230+
- E: Exploring
231+
- Q: Querying
232+
- R: Viewing results
233+
234+
Connecting: Connecting to a server
235+
Exploring: Understanding the structure and content of the databases
236+
Querying: Executing SQL queries
237+
D: Viewing the results of SQL queries
238+
239+
Additionally, we have requirements 'EAFF':
240+
241+
- E: Easy
242+
- A: Aesthetically pleasing
243+
- F: Fun
244+
- F: Fast
245+
246+
If an idea or feature does *not* achieve any of the 'CBQV' elements adhering to all of the 'EAFF' requirements. It does not belong to sqlit.
247+
248+
**[E]asy:**
249+
Sqlit should not require any external documentation at all. It must prioritize intuitiveness above all.
250+
251+
**[A]esthetically pleasing:**
252+
Sqlit should not render one unnecessary pixel. It should prioritize beauty above anything. Minimalism over bloat.
253+
254+
**Fun:**
255+
Sqlit aims make fulfilling its core purpose be an enjoyable experience for the user, even a source of pleasure.
256+
257+
**Fast:**
258+
Sqlit aims to fulfill its core purpose for the user, with intention to giving the user the results they want with as few actions as possible.
259+
260+
Essentially, sqlit aims to do CRUD on SQL really well.
261+
262+
This implies this tool is more suited for developer's daily use than an database administrator.
263+
Every feature in sqlit should have a target audience in which they will use it every time they use sqlit.
264+
If nobody is going to a feature every day. It does not belong to sqlit.
265+
E.g.
266+
267+
1) advanced query performance debugging -> rarely used -> does not belong in sqlit
268+
2) edit cell key-binding -> a audience who will use this every day -> belongs to sqlit
269+
270+
**On complexity:**
271+
Minimalism: sqlit aims to abstract away as much complexity as possible from the user, while giving them enough control to achieve CBQV. sqlit should never do anything under the hood that the user might have interest in understanding. Universal state problems deem for magical fixes. Conditional state problems, explicit user awareness. User should never ask "wait, how did it know?" "why is this here?" "why did it work then, but not now?"
272+
273+
Voluntary advanced usage: Anything beyond most essentials to achieve CEQR should be voluntary to be exposed to. Minimal cogntive overhead. Always assume by default our user just wants to perform CRUD with SQL.
274+
275+
The idea is the user is exposed to an interface that's minimalistic and easy, but if they want to become 'power users' they may dig into command menu or see help and memorize.
276+
277+
Advances features should not be advertised on the main tool bar or anywhere else where the user has no say in whether it's rendered, as they take up space and distract from the most essential features for crud.
278+
279+
One state: There should be no settings or preferences with important exception of interface (aesthetics, keyboard bindings). No settings to enable or disable features for conditional behaviour. Do not include a feature that a user finds annoying. Settings to disable a feature is a symptom of this. Anything beyond essential must be sought after if needed, not disabled if unwanted.
280+
281+
**Keybindings philosophy:**
282+
To make sqlit as fast' as possible, sqlit has a large focus on keybindings.
283+
To make sqlit as 'easy' as possible, all necessary keybindings to do 'CEQR' well, must be visible at all times.
284+
To make sqlit as 'aesthetically pleasing' any keybinding not strictly necessary to perform 'CEQR' in a 'easy' and 'fast' way will be hidden behind help <?> or command menu <space>
285+
Keybindings will favour 'vim' traditions as the core audience is developers who enjoy working in terminals.
286+
We shy away from ^+ commands and will only use them where it is not natural to have a "insert/normal" mode and where input is crucial. (Typical is pop up modals)
287+
288+
**Ideal:**
289+
It should be easy to use for someone who just started using sqlit.
290+
sqlit should provide fun and a feeling of mastery and satisfaction for those who want to achieve it, by becoming a sql-manipulating wizard with creative keybinding combos.
291+
292+
**Designing keybindings decision hierarchy:**
293+
294+
1. Intuitive to learn
295+
2. Harmony (we should think about which keybindings are used in sequence, in typical to flow and maximize user mastery satisfaction and opportunity to combine them fast)
296+
3. Traditions (vim, specifically)
297+
298+
**Example:**
299+
<e> = explorer pane, <q> = query pane, <r> = results pane.
300+
Rationale: E;Q;R satisfies both intuitiveness (each binding is the first letter of the pane), harmony (proximity: qwerty speaks for itself)
301+
211302
## License
212303

213304
MIT

demo-d1.gif

664 KB
Loading

demos/d1-demo.json

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
{
2+
"mock": {
3+
"enabled": true,
4+
"profile": "d1-demo",
5+
"connections": [],
6+
"adapters": {
7+
"d1": {
8+
"name": "Cloudflare D1",
9+
"default_schema": "main",
10+
"connect": {
11+
"result": "success"
12+
},
13+
"schemas": {
14+
"main": {
15+
"tables": {
16+
"users": {
17+
"columns": [
18+
{
19+
"name": "id",
20+
"type": "INTEGER"
21+
},
22+
{
23+
"name": "email",
24+
"type": "TEXT"
25+
},
26+
{
27+
"name": "name",
28+
"type": "TEXT"
29+
},
30+
{
31+
"name": "created_at",
32+
"type": "TEXT"
33+
}
34+
],
35+
"rows": [
36+
[
37+
1,
38+
"alice@example.com",
39+
"Alice Chen",
40+
"2024-11-01"
41+
],
42+
[
43+
2,
44+
"bob@example.com",
45+
"Bob Smith",
46+
"2024-11-05"
47+
],
48+
[
49+
3,
50+
"carol@example.com",
51+
"Carol Davis",
52+
"2024-11-10"
53+
]
54+
]
55+
},
56+
"posts": {
57+
"columns": [
58+
{
59+
"name": "id",
60+
"type": "INTEGER"
61+
},
62+
{
63+
"name": "user_id",
64+
"type": "INTEGER"
65+
},
66+
{
67+
"name": "title",
68+
"type": "TEXT"
69+
},
70+
{
71+
"name": "published",
72+
"type": "INTEGER"
73+
}
74+
],
75+
"rows": [
76+
[
77+
1,
78+
1,
79+
"Getting Started with D1",
80+
1
81+
],
82+
[
83+
2,
84+
1,
85+
"Edge Computing Basics",
86+
1
87+
],
88+
[
89+
3,
90+
2,
91+
"Workers and D1",
92+
0
93+
],
94+
[
95+
4,
96+
3,
97+
"SQLite at the Edge",
98+
1
99+
]
100+
]
101+
},
102+
"analytics": {
103+
"columns": [
104+
{
105+
"name": "id",
106+
"type": "INTEGER"
107+
},
108+
{
109+
"name": "post_id",
110+
"type": "INTEGER"
111+
},
112+
{
113+
"name": "views",
114+
"type": "INTEGER"
115+
},
116+
{
117+
"name": "date",
118+
"type": "TEXT"
119+
}
120+
],
121+
"rows": [
122+
[
123+
1,
124+
1,
125+
1250,
126+
"2024-12-01"
127+
],
128+
[
129+
2,
130+
2,
131+
890,
132+
"2024-12-01"
133+
],
134+
[
135+
3,
136+
4,
137+
445,
138+
"2024-12-01"
139+
],
140+
[
141+
4,
142+
1,
143+
320,
144+
"2024-12-02"
145+
]
146+
]
147+
}
148+
}
149+
}
150+
},
151+
"query_results": {
152+
"join": {
153+
"columns": [
154+
"author",
155+
"title",
156+
"total_views"
157+
],
158+
"rows": [
159+
[
160+
"Alice Chen",
161+
"Getting Started with D1",
162+
1570
163+
],
164+
[
165+
"Alice Chen",
166+
"Edge Computing Basics",
167+
890
168+
],
169+
[
170+
"Carol Davis",
171+
"SQLite at the Edge",
172+
445
173+
]
174+
]
175+
}
176+
}
177+
}
178+
}
179+
},
180+
"theme": "sqlit",
181+
"expanded_nodes": [
182+
"conn:My D1 Database",
183+
"conn:My D1 Database/folder:tables"
184+
]
185+
}

demos/demo-docker-picker.gif

587 KB
Loading

demos/demo-filter/demo-filter.gif

688 KB
Loading

0 commit comments

Comments
 (0)