Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,31 @@
# Python
__pycache__/
*.py[cod]
*.pyc
*.pyo
*.pyd
.Python
env/
venv/
.venv/

# Build artifacts
dist/
build/
*.egg-info/
*.egg

# Other
.DS_Store
*.log
*.pot
*.pytx
*.swp
.idea/
.vscode/
*.db
*.sqlite
*.sqlite3
/downloads
/node_modules
*.deb
*.rpm
5 changes: 5 additions & 0 deletions src/sqliteviewer.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Requires-Dist: build>=1.0.3; extra == "dev"
Dynamic: license-file

# SQLite Viewer for Ubuntu
⚠️ This repository is an experimental project using AI tools such as Codex.
It is shared for educational purposes only. Please note that it is provided *as is*, without warranty or official support.

A lightweight PyQt6 desktop SQLite database viewer targeting Ubuntu desktops. The app lets you inspect tables, run ad-hoc queries, and export results—packaged for distribution via Python wheels or Debian packages.

Expand Down Expand Up @@ -78,6 +80,9 @@ source .venv/bin/activate
pip install --upgrade pip
pip install -e ".[dev]"
```
Keep the extras in quotes (the `".[dev]"` part) so shells like `zsh` don't treat it as a glob pattern.

If you prefer `uv`, install it beforehand (for example `pip install uv`) and then run `uv pip install -e ".[dev]"` inside the virtual environment.

Launch the viewer:

Expand Down
3 changes: 2 additions & 1 deletion src/sqliteviewer.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ src/sqliteviewer.egg-info/top_level.txt
src/sqliteviewer/resources/__init__.py
src/sqliteviewer/resources/icon.png
src/sqliteviewer/resources/sqliteviewer.desktop
tests/test_database.py
tests/test_database.py
tests/test_mainwindow.py
2 changes: 2 additions & 0 deletions src/sqliteviewer/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ def _show_about_dialog(self) -> None:
def _load_recent_files(self) -> None:
files = self.settings.value("recent_files", [], type=list)
self._recent_files = [f for f in files if Path(f).exists()]
if len(self._recent_files) != len(files):
self.settings.setValue("recent_files", self._recent_files)
self._update_recent_menu()

def _remember_recent_file(self, path: str) -> None:
Expand Down
41 changes: 41 additions & 0 deletions tests/test_mainwindow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from __future__ import annotations

import tempfile
from pathlib import Path

import pytest
from PyQt6.QtCore import QSettings

from sqliteviewer.mainwindow import MainWindow


@pytest.fixture
def test_settings(qtbot) -> QSettings:
"""Override QSettings to use a temporary, clean .ini file for tests."""
QSettings.setDefaultFormat(QSettings.Format.IniFormat)
settings = QSettings("test-org", "test-app")
settings.clear()
yield settings
settings.clear()


def test_recent_files_are_purged_on_load(qtbot, test_settings, monkeypatch):
"""Verify that non-existent recent files are removed from settings on load."""
# Arrange: Use monkeypatch to ensure the MainWindow uses our test_settings instance.
monkeypatch.setattr(
"sqliteviewer.mainwindow.QSettings", lambda *args, **kwargs: test_settings
)

with tempfile.NamedTemporaryFile() as tmpfile:
real_path = Path(tmpfile.name).as_posix()
fake_path = "/tmp/this-file-definitely-does-not-exist.db"
initial_files = [real_path, fake_path]
test_settings.setValue("recent_files", initial_files)

# Act: create the main window, which should trigger the load
window = MainWindow()
qtbot.addWidget(window)

# Assert: the settings should now only contain the real path
stored_files = test_settings.value("recent_files", [], type=list)
assert stored_files == [real_path]
Loading