# DB Query

> Step 0 — Load configuration

- Skill: `weorbitant/db-query` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add weorbitant/db-query`
- Raw SKILL.md: https://api.skillmd.com/api/skills/weorbitant/db-query/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools, Data & Analytics
- Author: weorbitant (https://skillmd.com/u/weorbitant)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/weorbitant/db-query

---


## Step 0 — Load configuration

Check if `/tmp/ops-suite-session/config.json` exists:
- If yes, read it (pre-parsed by session-start hook).
- If no, read `${XDG_CONFIG_HOME:-$HOME/.config}/ops-suite/config.yaml` (preferred) or the plugin's `config.yaml` (legacy), parse it, and write to `/tmp/ops-suite-session/config.json` for other skills to reuse.
If neither exists, tell the user to run `/ops-suite:configure` (or copy `config.example.yaml` to `~/.config/ops-suite/config.yaml` and fill in their values). Stop here.

Extract:
- `database` — determines which adapter to load (postgresql, mysql, mongodb)
- `orchestrator` — for port-forward commands
- `environments` — connection details
- `deploy.local_ports` — local ports for database connections

Also read the reference at `references/query-examples.md` (in this skill's directory) for common query patterns.

## Step 1 — Load adapter

Read the adapter file at `adapters/{database}.md` (in this skill's directory).
If the adapter does not exist, tell the user that the database `{database}` is not yet supported and stop.

## Step 2 — Determine target environment

If `$ARGUMENTS` contains an environment name, use it. Otherwise ask the user.

## Step 3 — Establish database connection

Check if a port-forward is already active on the expected local port (`deploy.local_ports.{env_name}`).

If not active:
1. Start a port-forward using the orchestrator:
   ```
   kubectl --context={env.context} port-forward svc/{env.services.database.name} {deploy.local_ports.{env_name}}:{env.services.database.port} -n {env.services.database.namespace || env.namespaces.infra} &
   ```
2. Verify the connection is working

Retrieve or ask for credentials. Never hardcode credentials.

## Step 4 — Formulate query

If `$ARGUMENTS` contains a natural language description:
- Translate it into a SQL query (or equivalent for the database type)
- Show the query to the user and ask for confirmation before running

If `$ARGUMENTS` contains raw SQL:
- Use it directly, but validate it first

**Constraints:**
- Default to read-only queries (SELECT, EXPLAIN)
- If the user requests a write operation (INSERT, UPDATE, DELETE), warn them and ask for explicit confirmation
- Always use LIMIT to prevent unbounded result sets (default LIMIT 50)
- Wrap queries in a transaction with ROLLBACK for safety when testing writes

## Step 5 — Execute query

Use the adapter's query execution command.
The script at `scripts/query.js` (in this skill's directory) can be used as a helper for PostgreSQL.

## Step 6 — Format and present results

Present results in a clear, readable format:

```
Environment: {env_name}
Database:    {database_name}
Query:       {sql_query}
Rows:        {row_count}

Results:
| column_1 | column_2 | column_3 |
|----------|----------|----------|
| value    | value    | value    |

Query time: {duration}ms
```

If results are too many to display, show the first 20 rows and provide the total count.

## Step 7 — Cleanup

If a port-forward was started in this session, provide the cleanup command but do not kill it automatically (the user may want to run more queries).

## Important notes

- Always use parameterized queries when possible to prevent SQL injection
- Be aware of PgBouncer limitations: avoid multi-statement queries, SET commands, or prepared statements when connecting through PgBouncer
- For large datasets, suggest using EXPLAIN ANALYZE first to estimate query cost

