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.
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'] });Tipos de coluna
Seção intitulada “Tipos de coluna”| 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.
Colunas e índices ficam prontos em segundo plano
Seção intitulada “Colunas e índices ficam prontos em segundo plano”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.
Índices
Seção intitulada “Índices”Í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.