[data-reveal]{opacity:1!important;transform:none!important}
Table Operations
Database

Table Operations

Tables are the primary containers for documents in AQL. They are accessed through a SchemaInstance and provide methods for inserting, retrieving, and querying documents.

Access a Table

Retrieve a table reference from a schema instance:

import { Schema } from "@antelopejs/interface-database";

const schema = Schema.get("myapp")!;
const db = schema.instance();
const users = db.table("users");

Type-Safe Tables

Provide the table-to-document mapping to Schema, not to table():

import { Schema } from "@antelopejs/interface-database";

interface User {
  _id: string;
  name: string;
  email: string;
  status: string;
  role: string;
  createdAt: Date;
  age: number;
}

const schema = new Schema<{ users: User }>("myapp", {
  users: {
    fields: {
      name: "string",
      email: "string",
      status: "string",
      role: "string",
      createdAt: "date",
      age: "number",
    },
    indexes: { role: {}, createdAt: {}, name: {} },
  },
});
const users = schema.instance().table("users");

// TypeScript now validates field names and types
export async function readUser() {
  const user = await users.get("user-123"); // Declared as User
  const emails = await users.key("email"); // string[]
  return { user, emails };
}

get() declares SingleSelection<User>, so awaiting it is typed as User, not User | null. This declaration does not guarantee that a row exists: a provider may return null for a missing key. Check the result before accessing fields. Schema's generic mapping describes documents but does not validate database contents.

Basic Operations

Retrieve All Documents

A table reference doubles as a stream of all its documents:

const allUsers = await users;
console.log(`Total users: ${allUsers.length}`);

Retrieve by Primary Key

const user = await users.get("user-123");

if (user) {
  console.log("Found:", user.name);
}

Retrieve by Secondary Index

const admins = await users.getAll("admin", "role");

Retrieve by Range

const recent = await users.between(
  "createdAt",
  new Date("2024-01-01"),
  new Date(),
);

Chain Operations

Since Table extends Selection and Stream, you can chain any stream operation directly:

// Filter and sort
const activeByName = await users
  .filter((u) => u.key("status").eq("active"))
  .orderBy("name");

// Paginate
const page = await users.orderBy("createdAt").slice(0, 10);

// Aggregate
const count = await users.count();
const avgAge = await users.avg("age");

// Transform
const names = await users.map((u) => u.key("name"));

Insert Documents

// Single document
const ids = await users.insert({
  name: "Alice",
  email: "[email protected]",
  status: "active",
});

// Multiple documents
const batchIds = await users.insert([
  { name: "Bob", email: "[email protected]", status: "active" },
  { name: "Carol", email: "[email protected]", status: "active" },
]);

// Upsert (update on conflict)
await users.insert(
  { _id: "user-123", name: "Updated" },
  { conflict: "update" },
);

For complete CRUD documentation, see CRUD Operations.