Pular para o conteúdo

Bloco DB

O bloco DB é um bloco de código fenced markdown cuja linguagem é db-<connection-name>, onde <connection-name> é uma key do connections.toml. Cada conexão auto-registra o próprio tipo de bloco.

```db-local
SELECT id, name FROM users LIMIT 10
```

A linguagem do fence é db-local porque tem uma entrada [connections.local] no connections.toml.

TipoConnection stringNotas
sqlitepath = "./file.sqlite"Auto-cria o arquivo na primeira execução
postgreshost, port, database, user, password, ssl_modeDriver sqlx postgres
mysqlhost, port, database, user, passwordDriver sqlx mysql

Veja config-files pro schema completo de connections.toml.

TokenDefaultNotas
alias=<name>nenhumObrigatório pra captura/cadeia ({{users.row[0].id}}).
timeout=<ms>60000Timeout de query em milissegundos.
display=<mode>splitLayout do painel (mesmo que HTTP).

A linguagem do fence é a conexão — não tem token connection= separado.

Referências {{...}} no body SQL são sempre convertidas pra bind parameters. Nunca são string-interpolated.

```db-local
SELECT * FROM orders
WHERE customer_id = {{user.body.id}}
AND status = {{filter.body.status}}
```

O que o driver vê:

SELECT * FROM orders
WHERE customer_id = $1
AND status = $2

Valores de bind: [user.body.id, filter.body.status].

Zero superfície de SQL injection. Mesmo com valores controlados pelo usuário vindo de responses HTTP, o binding de prepared-statement do driver lida com coerção de tipo e escape.

Quando um bloco contém DELETE, UPDATE, INSERT, TRUNCATE, DROP ou ALTER, o httui mostra um banner de confirmação antes de rodar:

⚠ Esse bloco contém UPDATE. Rodar mesmo assim?

O guard é estrutural — o httui faz parse do SQL com um scanner, não um regex na primeira palavra. Então:

  • UPDATE dentro de comentário -- não é flagueado.
  • Um DELETE enterrado depois de um SELECT num bloco multi-statement é flagueado.

Desabilite por bloco via engrenagem da toolbar → Skip mutation prompt (persistido por bloco na info-string). Bom pra runbooks em que você confia e roda com frequência.

Você pode botar várias statements SQL num bloco, separadas por ponto e vírgula:

```db-local
CREATE TEMP TABLE staging AS SELECT * FROM users WHERE active = false;
DELETE FROM staging WHERE created_at &lt; unixepoch() - 30 * 86400;
SELECT count(*) FROM staging;
```

O mutation guard flagga se qualquer statement é destrutiva. Resultados vêm só da última statement — o grid de resultado mostra as linhas do SELECT final.

O painel de response tem um grid virtualizado pros resultados SELECT:

  • Headers de coluna ordenáveis (clique)
  • Badge de tipo por coluna (int, text, jsonb, etc)
  • Botão copy-as-CSV
  • Renderização janelada — 100k+ linhas ficam scrolláveis

Pra blocos de mutação (INSERT/UPDATE/DELETE), o painel mostra “N rows affected” + o tempo decorrido.

A primeira linha de todo resultado é a “response” implícita — encadeie nela em blocos seguintes:

```db-local alias=users_list
SELECT id, email FROM users ORDER BY id LIMIT 1
```
```http
GET {{BASE_URL}}/users/{{users_list.row[0].id}}
```

Campos disponíveis numa response de bloco DB:

CampoSignificado
row[N].<col>valor da coluna da n-ésima linha
rowsarray completo de resultado (raro encadear)
rows.lengthnúmero de linhas
affectedlinhas afetadas por mutação

Rode qualquer EXPLAIN ANALYZE (Postgres / MySQL) ou EXPLAIN QUERY PLAN (SQLite) e o painel renderiza o plano como tree view:

  • Scans sequenciais com custo alto são destacados em vermelho
  • Joins nested-loop com estimativas de cardinalidade ruins são flagueados
  • Botão-direito em qualquer nó → Copy as TEXT pra compartilhar

Pra conexões onde você precisa fazer SSH-tunnel local mas o connections.toml compartilhado aponta pro hostname de produção, use o diálogo ⚙ Session override da toolbar:

host: 127.0.0.1
port: 15432

Override é só-sessão — não persiste pro disco, aplicado por run de DB. Connection pool base fica intocado; o httui cria um pool override-keyed pra sessão de override. Útil pra trabalho pontual de tunnel sem editar .local.toml.

Mesmo hash SHA-256 dos blocos HTTP:

texto SQL (depois da substituição de bind) + valores de bind
+ snapshot do env (só vars referenciadas)

Statements de mutação (INSERT/UPDATE/DELETE/TRUNCATE/DROP/ALTER) nunca cacheam — sempre re-executam. Resultados de SELECT cacheam; limpe via engrenagem da toolbar → Clear cache.

Clique na aba Schema na sidebar pra navegar o schema da conexão ativa — tabelas, colunas com tipos, foreign keys, índices, estimativas de count de linha.

Schemas são introspecionados na abertura da conexão + cacheados em notes.db. Clique no ícone de refresh pra re-introspecionar (útil depois de uma migration).

Autocomplete schema-aware dispara dentro de blocos DB: digite um nome de tabela, ganhe sugestões de coluna; digite um nome de coluna, ganhe info de tipo.

AtalhoAção
Cmd+EnterRodar bloco
Cmd+.Cancelar query em execução
Cmd+Shift+ERodar como EXPLAIN (envolve a query)
MensagemCausaCorreção
connection refusedDB não alcançávelCheque host/port, túnel, firewall
relation "X" does not existSchema / search_path erradoUse nome fully-qualified public.X
password authentication failedCredenciais erradasAtualize via Environment manager (veja secrets)
pool exhaustedQueries concorrentes demais contra a mesma connReduza paralelismo no Run-all