Skip to content

Commit 3482b71

Browse files
authored
Hyperoptimization (#64)
* Hyperoptimizied * Uhh getting somewhere * Nice optimiations * Fix werid little thing * Fix * Telescope * Reactive connection map * Nice telescope * sqlit is the best now * Betterhelp * Better advice * Meh * Debug logging * Fix bug! * Fix telescope hangup bug * Nice telescope * Indexing is now off thread * Cleanups * Optional postgres host * Not execute queries automatically from telescope * Safer scheduler --------- Co-authored-by: Peter Adams <18162810+Maxteabag@users.noreply.github.com>
1 parent 037b901 commit 3482b71

Some content is hidden

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

65 files changed

+4776
-388
lines changed

config/settings.template.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
"theme": "tokyo-night",
44
"custom_themes": [],
55
"expanded_nodes": [],
6+
"process_worker": true,
7+
"process_worker_warm_on_idle": true,
8+
"process_worker_auto_shutdown_s": 0,
9+
"ui_stall_watchdog_ms": 0,
610
"allow_plaintext_credentials": false,
711
"mock": {
812
"enabled": true,

sqlit/core/keymap.py

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from abc import ABC, abstractmethod
66
from dataclasses import dataclass
77

8+
from sqlit.shared.core.debug_events import emit_debug_event
9+
810
KEY_DISPLAY_OVERRIDES: dict[str, str] = {
911
"question_mark": "?",
1012
"slash": "/",
@@ -118,7 +120,68 @@ def actions_for_key(self, key: str) -> list[str]:
118120
class DefaultKeymapProvider(KeymapProvider):
119121
"""Default keymap with hardcoded bindings."""
120122

123+
def __init__(self) -> None:
124+
self._leader_commands_cache: list[LeaderCommandDef] | None = None
125+
self._action_keys_cache: list[ActionKeyDef] | None = None
126+
self._leader_emitted: bool = False
127+
self._action_emitted: bool = False
128+
129+
def _emit_leader_keybindings(self, commands: list[LeaderCommandDef]) -> None:
130+
for cmd in commands:
131+
emit_debug_event(
132+
"keybinding.register",
133+
category="keybinding",
134+
kind="leader",
135+
provider=self.__class__.__name__,
136+
key=cmd.key,
137+
action=cmd.action,
138+
label=cmd.label,
139+
group=cmd.category,
140+
menu=cmd.menu,
141+
guard=cmd.guard,
142+
)
143+
144+
def _emit_action_keybindings(self, bindings: list[ActionKeyDef]) -> None:
145+
for binding in bindings:
146+
emit_debug_event(
147+
"keybinding.register",
148+
category="keybinding",
149+
kind="action",
150+
provider=self.__class__.__name__,
151+
key=binding.key,
152+
action=binding.action,
153+
context=binding.context,
154+
guard=binding.guard,
155+
primary=binding.primary,
156+
show=binding.show,
157+
priority=binding.priority,
158+
)
159+
160+
def _ensure_leader_commands(self) -> list[LeaderCommandDef]:
161+
if self._leader_commands_cache is None:
162+
self._leader_commands_cache = self._build_leader_commands()
163+
return self._leader_commands_cache
164+
165+
def _ensure_action_keys(self) -> list[ActionKeyDef]:
166+
if self._action_keys_cache is None:
167+
self._action_keys_cache = self._build_action_keys()
168+
return self._action_keys_cache
169+
121170
def get_leader_commands(self) -> list[LeaderCommandDef]:
171+
commands = self._ensure_leader_commands()
172+
if not self._leader_emitted:
173+
self._emit_leader_keybindings(commands)
174+
self._leader_emitted = True
175+
return list(commands)
176+
177+
def get_action_keys(self) -> list[ActionKeyDef]:
178+
bindings = self._ensure_action_keys()
179+
if not self._action_emitted:
180+
self._emit_action_keybindings(bindings)
181+
self._action_emitted = True
182+
return list(bindings)
183+
184+
def _build_leader_commands(self) -> list[LeaderCommandDef]:
122185
return [
123186
# View
124187
LeaderCommandDef("e", "toggle_explorer", "Toggle Explorer", "View"),
@@ -130,6 +193,8 @@ def get_leader_commands(self) -> list[LeaderCommandDef]:
130193
LeaderCommandDef("z", "cancel_operation", "Cancel", "Actions", guard="query_executing"),
131194
LeaderCommandDef("t", "change_theme", "Change Theme", "Actions"),
132195
LeaderCommandDef("h", "show_help", "Help", "Actions"),
196+
LeaderCommandDef("space", "telescope", "Telescope", "Actions"),
197+
LeaderCommandDef("slash", "telescope_filter", "Telescope Search", "Actions"),
133198
LeaderCommandDef("q", "quit", "Quit", "Actions"),
134199
# Delete menu (vim-style)
135200
LeaderCommandDef("d", "line", "Delete line", "Delete", menu="delete"),
@@ -222,7 +287,7 @@ def get_leader_commands(self) -> list[LeaderCommandDef]:
222287
LeaderCommandDef("j", "json", "Export as JSON", "Export", menu="rye"),
223288
]
224289

225-
def get_action_keys(self) -> list[ActionKeyDef]:
290+
def _build_action_keys(self) -> list[ActionKeyDef]:
226291
return [
227292
# Tree actions
228293
ActionKeyDef("n", "new_connection", "tree"),
@@ -243,6 +308,7 @@ def get_action_keys(self) -> list[ActionKeyDef]:
243308
# Global
244309
ActionKeyDef("space", "leader_key", "global", priority=True),
245310
ActionKeyDef("ctrl+q", "quit", "global"),
311+
ActionKeyDef("escape", "cancel_operation", "global"),
246312
ActionKeyDef("question_mark", "show_help", "global"),
247313
# Navigation
248314
ActionKeyDef("e", "focus_explorer", "navigation"),
@@ -322,9 +388,62 @@ def set_keymap(provider: KeymapProvider) -> None:
322388
"""Set the keymap provider (for testing or custom keymaps)."""
323389
global _keymap_provider
324390
_keymap_provider = provider
391+
emit_keybinding_snapshot(provider)
325392

326393

327394
def reset_keymap() -> None:
328395
"""Reset to default keymap provider."""
329396
global _keymap_provider
330397
_keymap_provider = None
398+
399+
400+
def emit_keybinding_snapshot(provider: KeymapProvider | None = None) -> None:
401+
"""Emit debug events for the current keymap bindings."""
402+
keymap = provider or get_keymap()
403+
if hasattr(keymap, "_ensure_leader_commands"):
404+
commands = keymap._ensure_leader_commands() # type: ignore[attr-defined]
405+
else:
406+
commands = keymap.get_leader_commands()
407+
for cmd in commands:
408+
emit_debug_event(
409+
"keybinding.register",
410+
category="keybinding",
411+
source="snapshot",
412+
kind="leader",
413+
provider=keymap.__class__.__name__,
414+
key=cmd.key,
415+
action=cmd.action,
416+
label=cmd.label,
417+
group=cmd.category,
418+
menu=cmd.menu,
419+
guard=cmd.guard,
420+
)
421+
if hasattr(keymap, "_leader_emitted"):
422+
try:
423+
keymap._leader_emitted = True # type: ignore[attr-defined]
424+
except Exception:
425+
pass
426+
if hasattr(keymap, "_ensure_action_keys"):
427+
bindings = keymap._ensure_action_keys() # type: ignore[attr-defined]
428+
else:
429+
bindings = keymap.get_action_keys()
430+
for binding in bindings:
431+
emit_debug_event(
432+
"keybinding.register",
433+
category="keybinding",
434+
source="snapshot",
435+
kind="action",
436+
provider=keymap.__class__.__name__,
437+
key=binding.key,
438+
action=binding.action,
439+
context=binding.context,
440+
guard=binding.guard,
441+
primary=binding.primary,
442+
show=binding.show,
443+
priority=binding.priority,
444+
)
445+
if hasattr(keymap, "_action_emitted"):
446+
try:
447+
keymap._action_emitted = True # type: ignore[attr-defined]
448+
except Exception:
449+
pass

sqlit/domains/connections/app/connection_flow.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
from collections.abc import Callable
56
from dataclasses import dataclass
67
from typing import Any, Protocol
78

@@ -25,6 +26,15 @@ class ConnectionFlow:
2526
services: AppServices
2627
connection_manager: Any | None = None
2728
prompter: ConnectionPrompter | None = None
29+
emit_debug: Callable[..., None] | None = None
30+
31+
def _emit_debug(self, name: str, **data: Any) -> None:
32+
if not self.emit_debug:
33+
return
34+
try:
35+
self.emit_debug(name, **data)
36+
except Exception:
37+
pass
2838

2939
def populate_credentials_if_missing(self, config: ConnectionConfig) -> None:
3040
"""Populate missing credentials from the credentials service."""
@@ -47,12 +57,28 @@ def populate_credentials_if_missing(self, config: ConnectionConfig) -> None:
4757
def start(self, config: ConnectionConfig, on_ready: Any) -> None:
4858
"""Start the connection flow, prompting for missing passwords as needed."""
4959
self.populate_credentials_if_missing(config)
60+
self._emit_debug(
61+
"connection_flow.start",
62+
connection=config.name,
63+
db_type=str(config.db_type),
64+
needs_ssh=needs_ssh_password(config),
65+
needs_db=needs_db_password(config),
66+
has_db_password=bool(config.tcp_endpoint and config.tcp_endpoint.password is not None),
67+
has_ssh_password=bool(config.tunnel and config.tunnel.password is not None),
68+
)
5069

5170
if needs_ssh_password(config):
5271
if not self.prompter:
72+
self._emit_debug("connection_flow.ssh_prompt_missing", connection=config.name)
5373
return
5474

5575
def on_ssh_password(password: str | None) -> None:
76+
self._emit_debug(
77+
"connection_flow.ssh_password",
78+
connection=config.name,
79+
provided=password is not None,
80+
value_len=len(password) if password is not None else 0,
81+
)
5682
if password is None:
5783
return
5884
temp_config = config.with_tunnel(password=password)
@@ -66,15 +92,29 @@ def on_ssh_password(password: str | None) -> None:
6692
def _with_db_password(self, config: ConnectionConfig, on_ready: Any) -> None:
6793
if needs_db_password(config):
6894
if not self.prompter:
95+
self._emit_debug("connection_flow.db_prompt_missing", connection=config.name)
6996
return
7097

7198
def on_db_password(password: str | None) -> None:
99+
self._emit_debug(
100+
"connection_flow.db_password",
101+
connection=config.name,
102+
provided=password is not None,
103+
value_len=len(password) if password is not None else 0,
104+
)
72105
if password is None:
73106
return
74107
temp_config = config.with_endpoint(password=password)
108+
self._emit_debug(
109+
"connection_flow.ready",
110+
connection=config.name,
111+
db_type=str(config.db_type),
112+
source="db_prompt",
113+
)
75114
on_ready(temp_config)
76115

77116
self.prompter.prompt_db_password(config, on_db_password)
78117
return
79118

119+
self._emit_debug("connection_flow.ready", connection=config.name, db_type=str(config.db_type))
80120
on_ready(config)

sqlit/domains/connections/app/url_parser.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,13 @@ def _parse_server_based_url(
186186
) -> ConnectionConfig:
187187
"""Parse a server-based database URL (PostgreSQL, MySQL, etc.)."""
188188
hostname = parsed.hostname or ""
189-
if not hostname:
189+
schema = get_provider_schema(db_type)
190+
requires_host = True
191+
for field in schema.fields:
192+
if field.name == "server":
193+
requires_host = field.required
194+
break
195+
if requires_host and not hostname:
190196
raise ValueError(f"No host specified in URL: {original_url}")
191197

192198
# Extract and decode credentials

sqlit/domains/connections/providers/postgresql/adapter.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,17 @@ def connect(self, config: ConnectionConfig) -> Any:
4848
endpoint = config.tcp_endpoint
4949
if endpoint is None:
5050
raise ValueError("PostgreSQL connections require a TCP-style endpoint.")
51-
port = int(endpoint.port or get_default_port("postgresql"))
5251
connect_args: dict[str, Any] = {
53-
"host": endpoint.host,
54-
"port": port,
55-
"database": endpoint.database or "postgres",
56-
"user": endpoint.username,
57-
"password": endpoint.password,
5852
"connect_timeout": 10,
53+
"database": endpoint.database or "postgres",
5954
}
55+
if endpoint.host:
56+
connect_args["host"] = endpoint.host
57+
connect_args["port"] = int(endpoint.port or get_default_port("postgresql"))
58+
if endpoint.username:
59+
connect_args["user"] = endpoint.username
60+
if endpoint.password is not None:
61+
connect_args["password"] = endpoint.password
6062

6163
tls_mode = get_tls_mode(config)
6264
tls_ca, tls_cert, tls_key, tls_key_password = get_tls_files(config)

sqlit/domains/connections/providers/postgresql/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
db_type="postgresql",
1616
display_name="PostgreSQL",
1717
fields=(
18-
_server_field(),
18+
_server_field(required=False),
1919
_port_field("5432"),
2020
_database_field(),
21-
_username_field(),
21+
_username_field(required=False),
2222
_password_field(),
2323
)
2424
+ SSH_FIELDS

sqlit/domains/connections/providers/schema_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ class ConnectionSchema:
5757

5858
# Common field templates
5959

60-
def _server_field(placeholder: str = "localhost") -> SchemaField:
60+
def _server_field(placeholder: str = "localhost", required: bool = True) -> SchemaField:
6161
return SchemaField(
6262
name="server",
6363
label="Server",
6464
placeholder=placeholder,
65-
required=True,
65+
required=required,
6666
group="server_port",
6767
)
6868

0 commit comments

Comments
 (0)