pgrs: Bikin CLI PostgreSQL Sendiri, dan Apa yang Saya Pelajari
Saya termasuk orang yang kerja harian dengan beberapa database PostgreSQL sekaligus — local, staging, production, plus database beberapa klien. Setiap kali mau ngecek data, ritualnya selalu sama: buka terminal, ketik ulang psql -h host -U user -d dbname, lupa password, buka password manager, copy-paste, baru bisa connect. Kalau environment-nya ada lima-enam, ritual ini terjadi berkali-kali sehari.
Lama-lama gatel. Kenapa nggak simpan saja koneksi-koneksi itu dengan nama yang gampang diingat, lalu tinggal panggil namanya? Dari rasa gatel itulah lahir pgrs — CLI dan REPL PostgreSQL untuk orang yang malas mengetik ulang connection string.
Idenya: koneksi tersimpan, bukan connection string yang diketik ulang
Hal pertama yang saya putuskan: cukup simpan koneksi sekali dengan nama, lalu panggil namanya kapan saja. Detail host, user, password, port, mode TLS — semua disimpan, bukan diketik ulang.
BASHpgrs add prod-db --host=db.example.com --username=postgres \ --password=secret --database=mydb --tls=verify-full --env=production pgrs connect prod-db
pgrs connect cukup meng-exec langsung ke psql — proses digantikan sepenuhnya, tanpa lapisan tambahan. Tapi saya juga ingin sesuatu yang lebih dari sekadar shortcut ke psql: autocomplete tabel/kolom, syntax highlighting, riwayat query yang tersimpan. Jadi ada mode kedua, pgrs shell, yang membuka REPL SQL bawaan:
BASH$ pgrs shell prod-db pgrs(prod-db:production)> select id, email from users limit 1; id | email ----+------------------ 1 | user@example.com pgrs(prod-db:production)>
Satu tool, dua cara pakai — connect untuk yang sudah biasa dengan psql, shell untuk sesi kerja yang lebih lama di satu database.
Transaction guard: mengerem sebelum melangkah
Ada satu titik ketika saya sadar REPL ini sudah cukup nyaman dipakai untuk hal yang seharusnya bikin was-was: menjalankan UPDATE atau DELETE langsung dari terminal tanpa jaring pengaman. Satu typo di klausa WHERE, dan seluruh tabel bisa berubah.
Jawabannya bukan fitur baru, tapi sebuah batasan: INSERT/UPDATE/DELETE (termasuk yang dibungkus CTE) ditolak kecuali ada transaksi terbuka lebih dulu.
BASHpgrs(prod-db:production)> delete from users where id = 1; error: INSERT/UPDATE/DELETE requires an explicit transaction. Run BEGIN (or \begin) first. pgrs(prod-db:production)> \begin BEGIN pgrs(prod-db:production)*> delete from users where id = 1; DELETE 1 pgrs(prod-db:production)*> \commit COMMIT
Prompt-nya sendiri berubah jadi *> begitu transaksi terbuka, jadi status transaksi selalu kelihatan tanpa perlu ditanyakan. pgrs connect (jalur psql langsung) sengaja tidak kena aturan ini — itu jalur untuk yang sudah sadar risikonya. Menambah fitur itu menyenangkan; menambah pengereman yang tepat di tool yang menyentuh data produksi itu yang justru terasa seperti kerja "beneran".
Autocomplete yang paham konteks, dan riwayat yang tidak pernah hilang
Autocomplete di pgrs bukan sekadar daftar kata kunci SQL. Ia membaca konteks: setelah FROM/JOIN ia menyarankan nama tabel, setelah SELECT/WHERE/ON ia menyarankan kolom — termasuk kolom milik tabel yang di-alias di klausa JOIN. Saran itu juga diurutkan berdasarkan frekuensi pemakaian, jadi tabel dan kolom yang sering saya sentuh muncul lebih dulu, bukan sekadar urutan alfabet.
Hal kecil lain yang ternyata paling sering saya rasakan manfaatnya: riwayat baris REPL (panah-atas untuk recall, Ctrl+R untuk reverse-search) disimpan per koneksi ke disk, dan ditulis ulang setelah setiap perintah — bukan hanya saat sesi ditutup dengan normal. Kalau terminal ke-close paksa atau proses crash di tengah kerja, riwayat query semalam tetap ada besok paginya.
Kenapa Rust dan hexagonal architecture
Saya pilih Rust karena binary tunggal tanpa runtime, cepat, dan cocok untuk tool yang dipakai ratusan kali sehari. Tapi keputusan yang lebih menentukan adalah arsitekturnya.
pgrs dibangun sebagai hexagonal architecture (ports & adapters), dipecah jadi dua crate: pgrs-core menyimpan seluruh domain, service, dan port (trait) — sedangkan pgrs-cli cuma berisi parsing argumen, REPL, dan tampilan. pgrs-cli hanya boleh bicara lewat facade publik pgrs-core (ConnectionApi, QueryApi, SchemaApi, dst); modul services/ports/adapters di dalam core bersifat pub(crate) dan tidak bisa dijangkau dari luar — batas ini ditegakkan oleh compiler, bukan sekadar konvensi.
Untuk proyek sekecil ini, pemisahan itu mungkin terdengar berlebihan. Tapi justru itu poinnya: setiap kali saya menambah fitur besar — REPL, autocomplete, \explain, transaction guard — saya merasakan sendiri kapan batas antar-layer itu menyelamatkan waktu. Logika SQL (tokenizer, alias-map, deteksi DDL/DML) bisa dites tanpa koneksi Postgres sungguhan, dan kalau suatu hari saya bikin pgrs-desktop atau pgrs-web, semua logika itu tinggal dipakai ulang tanpa ditulis dari nol.
Yang saya pelajari
Membangun pgrs mengajari saya beberapa hal yang tidak saya duga di awal:
- Fitur yang paling dipakai jarang yang paling canggih. Riwayat yang tidak hilang saat crash, atau pesan error yang jelas ketika salah ketik perintah, ternyata terasa lebih berharga sehari-hari daripada fitur besar yang jarang disentuh.
- Batasan adalah fitur juga. Transaction guard tidak menambah satu kemampuan pun ke pengguna — ia justru mengurangi apa yang bisa dilakukan tanpa sadar. Tapi itulah yang bikin tool ini terasa aman dipakai di database produksi.
- Parser sederhana cukup untuk 95% kasus — dan gagal diam-diam di 5% sisanya. Deteksi "statement selesai" yang awalnya cuma melacak tanda kutip ternyata kebobolan oleh komentar SQL dan dollar-quote (
$$...$$). Perbaikannya bukan tambal, tapi menulis ulang jadi lexer kecil yang benar-benar mengerti bentuk SQL. - Arsitektur yang bersih membayar lebih cepat dari dugaan. Bahkan di tool CLI kecil, batas yang jelas antara core dan CLI membuat saya berani menambah fitur besar tanpa takut merusak yang sudah ada.
Coba sendiri
pgrs open source, untuk Linux dan macOS. Satu baris ini sudah cukup untuk install:
BASHcurl -fsSL https://raw.githubusercontent.com/fakhrulnugroho/pgrs/main/install.sh | bash
Kode dan rilis terbarunya ada di github.com/fakhrulnugroho/pgrs (v0.9.0 adalah rilis terbaru saat tulisan ini dibuat). Kalau kamu juga sering kesal dengan hal-hal receh di workflow harian, coba jadikan itu satu project kecil — kadang itu yang paling menyenangkan untuk dibangun, karena kamu sendiri adalah user pertamanya.