Skip to content

Commit 0b92e35

Browse files
authored
Merge pull request #104 from bivashy/fix/inmemory-query-history-duplicatesf
[Fix] InMemory query history contains duplicates
2 parents b7ca616 + 75e1bc4 commit 0b92e35

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

sqlit/domains/query/store/memory.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from __future__ import annotations
44

55
from dataclasses import dataclass
6+
from datetime import datetime
67
from typing import Any
78

89
from sqlit.domains.query.store.history import QueryHistoryEntry
@@ -39,11 +40,22 @@ def load_all(self) -> list[QueryHistoryEntry]:
3940
return [QueryHistoryEntry.from_dict(entry) for entry in self._entries]
4041

4142
def save_query(self, connection_name: str, query: str) -> None:
42-
self._entries.append({
43-
"query": query.strip(),
44-
"timestamp": "",
45-
"connection_name": connection_name,
46-
})
43+
query_stripped = query.strip()
44+
now = datetime.now().isoformat()
45+
46+
# Check if query already exists
47+
for entry in self._entries:
48+
if entry.get("connection_name") == connection_name and entry.get("query", "").strip() == query_stripped:
49+
entry["timestamp"] = now
50+
break
51+
else:
52+
self._entries.append(
53+
{
54+
"query": query_stripped,
55+
"timestamp": now,
56+
"connection_name": connection_name,
57+
}
58+
)
4759

4860
def delete_entry(self, connection_name: str, timestamp: str) -> bool:
4961
return False

tests/ui/test_query_history.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from textual.widgets import OptionList
88

99
from sqlit.domains.query.store.history import QueryHistoryEntry
10+
from sqlit.domains.query.store.memory import InMemoryHistoryStore
1011
from sqlit.domains.query.ui.screens.query_history import QueryHistoryScreen
1112
from sqlit.domains.shell.app.main import SSMSTUI
1213

@@ -195,6 +196,34 @@ async def test_show_history_for_unsaved_connection_uses_session_history(self) ->
195196
option_list = screen.query_one("#history-list", OptionList)
196197
assert option_list.option_count == 1
197198

199+
@pytest.mark.asyncio
200+
async def test_show_history_for_unsaved_connection_with_duplicates(self) -> None:
201+
unsaved_conn = create_test_connection("temp-db", "sqlite")
202+
history_store = MockHistoryStore()
203+
services = build_test_services(
204+
connection_store=MockConnectionStore([]),
205+
settings_store=MockSettingsStore({"theme": "tokyo-night"}),
206+
history_store=history_store,
207+
)
208+
app = SSMSTUI(services=services)
209+
210+
async with app.run_test(size=(100, 35)) as pilot:
211+
app.current_config = unsaved_conn
212+
app._save_query_history(unsaved_conn, "SELECT 1")
213+
app._save_query_history(unsaved_conn, "SELECT 1")
214+
215+
app.action_show_history()
216+
await pilot.pause(0.2)
217+
218+
screen = next(
219+
(s for s in app.screen_stack if isinstance(s, QueryHistoryScreen)),
220+
None,
221+
)
222+
assert screen is not None, "History screen should be present"
223+
224+
option_list = screen.query_one("#history-list", OptionList)
225+
assert option_list.option_count == 1
226+
198227
def test_saved_connection_queries_saved(self) -> None:
199228
saved_conn = create_test_connection("saved-db", "sqlite")
200229
history_store = MockHistoryStore()

0 commit comments

Comments
 (0)