Pular para o conteúdo

Bancos, tabelas e colunas

Os dados ficam em tabelas com colunas tipadas, dentro de um banco. Um projeto pode ter vários bancos (por exemplo, um por área do produto). A estrutura se cria uma vez, pelo console (Banco → Criar banco → Criar tabela, abas Colunas e Índices) ou pelo servidor, com o @owbase/node e uma chave de API.

tabelas.ts (servidor)
import { Permission, Role, TablesDB, TablesDBIndexType } from '@owbase/node';
import { client } from './client';
// A chave precisa dos escopos databases.write, tables.write e columns.read.
const db = new TablesDB(client);
const tabela = { databaseId: 'loja', tableId: 'pedidos' };
await db.create({ databaseId: 'loja', name: 'Loja' });
await db.createTable({
...tabela,
name: 'Pedidos',
// Usuários logados criam pedidos; cada linha leva as próprias permissões (segurança por linha).
permissions: [Permission.create(Role.users())],
rowSecurity: true,
});
await db.createVarcharColumn({ ...tabela, key: 'cliente', size: 120, required: true });
await db.createIntegerColumn({ ...tabela, key: 'total', required: true, min: 0 });
await db.createEnumColumn({ ...tabela, key: 'status', elements: ['aberto', 'pago', 'enviado'], required: false, xdefault: 'aberto' });
await db.createDatetimeColumn({ ...tabela, key: 'entregaEm', required: false });
// Colunas ficam prontas em segundo plano: o índice só pode usar coluna com status "available".
async function esperarColuna(key: string): Promise<void> {
for (let i = 0; i < 60; i++) {
const coluna = await db.getColumn({ ...tabela, key });
if (String(coluna.status) === 'available') return;
await new Promise((r) => setTimeout(r, 1000));
}
throw new Error(`a coluna ${key} não ficou pronta em 60 s`);
}
await esperarColuna('status');
await db.createIndex({ ...tabela, key: 'por_status', type: TablesDBIndexType.Key, columns: ['status'] });
Tipo Método (TablesDB.) Observação
Texto curto createVarcharColumn com tamanho máximo (size); pode ter índice
Texto longo createTextColumn, createMediumtextColumn, createLongtextColumn para conteúdo extenso
Inteiro createIntegerColumn, createBigIntColumn min e max opcionais
Decimal createFloatColumn min e max opcionais
Sim/não createBooleanColumn
Data e hora createDatetimeColumn ISO 8601, em UTC
Lista fechada createEnumColumn valores em elements
E-mail, URL, IP createEmailColumn, createUrlColumn, createIpColumn validados pelo servidor
Relação createRelationshipColumn liga a outra tabela
Geografia createPointColumn, createLineColumn, createPolygonColumn coordenadas

A maioria das colunas aceita required (obrigatória), xdefault (valor padrão, só em coluna não obrigatória) e array: true (lista de valores). A coluna de relação não tem required. As de texto aceitam encrypt: true, que guarda o valor criptografado, mas uma coluna criptografada não pode ser consultada, e um índice nela não ajuda as consultas. Coluna de texto criptografada precisa de size de pelo menos 150.

Criar coluna ou índice devolve na hora com status: "processing"; o servidor termina em seguida e o status passa a available. Antes disso, a coluna não aceita valores nem entra num índice: o exemplo acima espera com getColumn. Se o status for failed, apague e crie de novo.

Índice deixa filtro e ordenação rápidos em tabela grande, e é obrigatório para Query.search.

TablesDBIndexType. Para
Key filtrar e ordenar
Unique garantir que o valor não se repita
Fulltext busca de texto (Query.search)
Spatial colunas de geografia

Um índice pode combinar várias colunas (columns: ['status', 'total']), na ordem em que as consultas filtram.

Próximo: criar e ler linhas e definir quem acessa.