Hafif bir masaüstü PostgreSQL client uygulaması. Rust + egui/eframe ile yazılmış. Hedef: DBeaver/DataGrip'e alternatif, <50MB RAM, <200ms startup.
Gerçek ölçümler (v0.2.x): ~45–47 MB RAM, 6.9 MB binary (release LTO)
- GUI: egui 0.27 + eframe (immediate-mode, pure Rust;
accesskitdevre dışı) - DB Driver: tokio-postgres 0.7 (async, pure Rust;
simple_querytext protokol) - Async: tokio (current-thread runtime, ayrı std::thread içinde)
- TLS: native-tls + postgres-native-tls
- SSH: russh 0.44
- Config: serde + toml
- Export: serde_json + manuel CSV
- File Dialog: rfd 0.14 (native OS diyaloğu)
- SQL Highlighting: sıfırdan yazılmış tokenizer —
src/ui/syntax.rs(syntect yok)
UI thread (eframe) ↔ DB thread arası haberleşme SADECE mpsc kanalları ile:
Sender<DbCommand>→ UI'dan DB'ye komutSender<DbEvent>→ DB'den UI'a sonuç- DB thread kendi
current_threadtokio runtime'ınıstd::thread::spawniçinde oluşturur spawn_blockingile sync recv, sonra async tokio-postgres
Bu pattern'i ASLA değiştirme. eframe main thread'i bloke eden hiçbir şey yapma.
src/
├── main.rs — eframe init, current_thread tokio runtime
├── app.rs — PgClientApp, eframe::App impl, event loop
├── config.rs — ConnectionProfile, AppConfig (TOML)
├── history.rs — QueryHistory (kalıcı, max 500)
├── logger.rs — crash log (panic hook)
├── db/
│ ├── mod.rs
│ ├── connection.rs — DbCommand/DbEvent, db_worker, execute_query (simple_query)
│ ├── query.rs — CellValue enum, QueryResult
│ ├── metadata.rs — Schema/table/column/index/FK introspection
│ └── ssh.rs — SSH tunnel (russh)
└── ui/
├── mod.rs
├── sidebar.rs — SidebarAction, schema tree, context menu
├── query_panel.rs — SQL editör, BrowseState, sayfalama
├── result_table.rs — egui_extras::TableBuilder, sort, inline edit
├── tab_manager.rs — Tab lifecycle, yönlendirme, sağ-tık menüsü
├── connection_dialog.rs
├── dashboard.rs — DB dashboard (tablo boyutları, bağlantılar, index)
├── explain.rs — EXPLAIN ANALYZE ağaç görünümü
├── er_diagram.rs — ER diyagramı
├── autocomplete.rs — Tablo/sütun otomatik tamamlama
└── syntax.rs — Sıfırdan SQL tokenizer (keyword/type/string/comment)
- Bağlantı profilleri:
~/.config/pgclient/config.toml - Sorgu geçmişi:
~/.local/share/pgclient/history.txt - Crash log:
~/.local/share/pgclient/crash.log
cargo build # dev
cargo build --release # ~6.9MB binary, LTOunwrap()kullanma —?veyaanyhowile hata yönet- UI'da blocking çağrı yapma (mpsc::recv hariç, o spawn_blocking içinde)
- Yeni UI widget'ları
src/ui/altına koy - Yeni DB sorguları
src/db/metadata.rsveyasrc/db/query.rs'e ekle DbCommand/DbEventenum'larınısrc/db/connection.rs'de tut- Tüm sorgular
execute_query()üzerinden geçmeli →simple_queryprotokol
- Tüm SQL'ler (SELECT, DML, DDL)
simple_queryile çalışır — noktalı virgül ve çoklu statement desteklenir ;ile ayrılmış birden fazla statement sırayla çalışır; son SELECT sonucu gösterilir- Boş tablo/view (0 satır):
prepare()ile sütun isimleri kurtarılır - SELECT-like sorgular hiçbir zaman
rows_affectedset etmez —set_result()DML detection'ı bu sayede doğru çalışır - Hard cap: 50.000 satır/sonuç (unbounded memory büyümesini önler)
- Tabloya tıklanınca: mevcut tab bulunursa switch, aktif tab boşsa reuse, doluysa yeni tab
- Sağ-tık context menu: Close tab / Close other tabs / Close all tabs
running_tabs: HashMap<conn_id, tab_idx>— sonuçları doğru taba yönlendirir
- Faz 0: Proje iskeleti, UI/DB thread ayrımı ✓
- Faz 1: Bağlantı dialog, SSL/TLS, profil kaydetme ✓
- Faz 2: Schema browser (lazy load, filtre, context menu) ✓
- Faz 3: Query editor, sonuç tablosu, virtual scrolling, client+DB sort ✓
- Faz 4: Data browser, sayfalama, DB-side ORDER BY, native export diyaloğu ✓
- Faz 5: Uygulama ikonu, release CI/CD, UI modernizasyon ✓
- Faz 6: Multi-statement queries, per-table tabs, view/matview browse fix, RAM optimizasyonları ✓
- Test Connection butonu (bağlantı dialog'unda)
- Ctrl+A ile tümünü seç (sorgu editörü)
- NULL renk tercihi config'e kaydet
- Büyük sonuç setlerinde column width hesabı lazy yap
src/app.rs:configure_style() — JetBrains Darcula paleti:
- Panel:
#2b2b2b, Window:#3c3f41, Faint:#313335 - Accent/seçim:
#4e9fde(mavi), Hover:#5c6164 - Run butonu:
#499c54(yeşil), Cancel:#c75450(kırmızı) - Yeni renk/spacing eklerken bu fonksiyonu güncelle, hardcode etme
src/ui/syntax.rs — sıfırdan yazılmış SQL tokenizer
- Syntect/once_cell yok — sıfır bağımlılık, ~0 MB overhead
- Byte-level scanner: keyword, type, function, string (single-quote + dollar-quote), number, comment (--, /* */), operator
highlight_sql(ui, text, wrap_width) -> LayoutJob- Dark:
base16-ocean.darkrenk paleti, Light:InspiredGitHubrenk paleti query_panel.rs'deTextEdit::layoutercallback'i olarak kullanılır