Pular para o conteúdo

SQLite (libSQL)

Um banco gerenciado é um serviço kind=database do projeto. Ele vive no nó de banco (outro host), não na rede privada do grupo: os apps o acessam pela URL com TLS. Escopo do token: databases:write (criar, apagar, rotacionar) e projects:read (ler). Veja Tokens e escopos.

name é o nome do serviço (^[a-z][a-z0-9-]{0,30}$, único no projeto; é o prefixo das referências ${{db.…}}). engine é postgres, mariadb ou sqlite; quota_mb é a cota em MB.

Janela do terminal
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
-d "{\"name\": \"demo-sq-$SUF\"}" | jq -r .id)
curl -sS -X POST "$NEBULAR_API/v1/projects/$P/databases" -H "$H" -H "Content-Type: application/json" \
-H "Idempotency-Key: sq-db-$SUF" \
-d '{"name": "db", "engine": "sqlite", "quota_mb": 1024}'
{"id": "01j9zktv26djn3k6dd2yraqsbt", "name": "db", "kind": "database", "engine": "sqlite", "status": "provisioning", "quota_mb": 1024}

O banco nasce em provisioning e vira ready. Consulte GET /v1/projects/$P/databases/{s} com backoff (2 s, dobrando até 30 s, até uns 10 min) até o banco estar pronto antes de fazer deploy dos dependentes:

Janela do terminal
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
-d "{\"name\": \"demo-sq-$SUF\"}" | jq -r .id)
DB=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/databases" -H "$H" -H "Content-Type: application/json" \
-H "Idempotency-Key: sq-db-$SUF" \
-d '{"name": "db", "engine": "sqlite", "quota_mb": 1024}' | jq -r .id)
delay=2
for i in $(seq 1 40); do
st=$(curl -sS "$NEBULAR_API/v1/projects/$P/databases/$DB" -H "$H" | jq -r .status)
echo "tentativa $i: $st"
[ "$st" = ready ] && break
sleep "$delay"; delay=$(( delay * 2 > 30 ? 30 : delay * 2 ))
done
curl -sS "$NEBULAR_API/v1/projects/$P/databases/$DB" -H "$H"
{"id": "01j9zktv26djn3k6dd2yraqsbt", "name": "db", "kind": "database", "engine": "sqlite", "status": "ready", "quota_mb": 1024, "read_only": false}

Todas sensíveis (mascaradas em log e UI) e referenciáveis por qualquer serviço do grupo:

Variável Conteúdo
LIBSQL_URL libsql://… do banco
LIBSQL_AUTH_TOKEN token de acesso (JWT) do banco
DATABASE_URL igual a LIBSQL_URL

A conexão é por TLS; o cliente libSQL usa LIBSQL_URL + LIBSQL_AUTH_TOKEN.

No app, use por referência (nunca copie o valor): ${{db.DATABASE_URL}}. Veja Conexão e referências.

Ler o valor em claro exige o escopo env:reveal num token criado com step-up (GET …/variables?resolved=true). Sem ele, o valor vem mascarado. As credenciais também saem de POST /v1/projects/{p}/databases/{s}/credentials (exige env:reveal): {"credentials": [{"name": "DATABASE_URL", "value": "..."}, ...]}.

Com as credenciais reveladas, use o SDK libSQL da sua linguagem com LIBSQL_URL e LIBSQL_AUTH_TOKEN (ilustrativo):

// SDK libSQL: createClient({ url: process.env.LIBSQL_URL, authToken: process.env.LIBSQL_AUTH_TOKEN })

quota_mb é medida a cada 5 minutos. Acima do limite o banco vira read_only (escritas falham; há evento e aviso ao time) e volta ao normal ao baixar do limite (apague dados). O motor sinaliza quota_exceeded (422) quando a cota é incompatível com o uso.

Para mudar a cota: PATCH /v1/projects/{p}/databases/{s} com {"quota_mb": 2048} (databases:write); a resposta é o banco (quota_mb, size_mb, read_only). GET /v1/projects/{p}/databases lista os bancos do projeto.

POST /v1/projects/{p}/databases/{s}/rotate (databases:write) troca a chave de assinatura do banco: o LIBSQL_AUTH_TOKEN anterior passa a dar 401 na hora e um token novo é selado. A URL não muda. Os serviços dependentes são marcados “precisam de redeploy” (re-resolução): faça deploy deles.

Janela do terminal
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
-d "{\"name\": \"demo-sq-$SUF\"}" | jq -r .id)
DB=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/databases" -H "$H" -H "Content-Type: application/json" \
-H "Idempotency-Key: sq-db-$SUF" \
-d '{"name": "db", "engine": "sqlite", "quota_mb": 1024}' | jq -r .id)
curl -sS -X POST "$NEBULAR_API/v1/projects/$P/databases/$DB/rotate" \
-H "$H"
{"id": "01j9zktv26djn3k6dd2yraqsbt", "name": "db", "kind": "database", "engine": "sqlite"}

DELETE /v1/projects/{p}/databases/{s} (databases:write; 204). Pela API de token a chamada não exige step-up (o painel exige); por padrão faz backup final antes ({"final_backup": false} no corpo desliga). Apagar é irreversível para os dados atuais; restaure do backup final se precisar (Backup e restore).

Resposta O que fazer
401 / 403 Token ausente/sem escopo databases:write. Peça um token com o escopo.
404 not_found Projeto ou banco inexistente ou de outro time (indistinguíveis). Confira os ids.
409 name_taken Já existe um serviço com esse name no projeto (todo banco é um serviço). Use outro name.
422 quota_exceeded Cota insuficiente para o uso atual. Apague dados ou peça cota maior.
503 unavailable Nó de banco indisponível. Repita com backoff (a mesma Idempotency-Key). Persistindo, pare e avise uma pessoa.
429 rate_limited Espere Retry-After.

Tabela completa: Erros.