Database — Select Data

Read rows with a small, fluent chain: db.from('<table>') → filters/modifiers → select('<projection>').

Prerequisite: You must have created a client with a required dbSpec (schema + relations [+ optional seed, meta]) and an adapter factory (SQLite Web/Expo or Supabase).


Execution Rule

  • In v1.0, .select(projection) executes the query.
  • Always chain filters/modifiers first, then call .select(...).
  • Writes (insert, update, delete) execute immediately.

Basics

1// All columns
2const users = await db.from('users').select('*')
3
4// Projection (only specific fields)
5const lite = await db.from('users').select('id, name, email')

Filters

Supported helpers: eq, ne, gt, gte, lt, lte, in, like
Or use a single object .where({...}).

1// Operator helpers
2const posts = await db
3  .from('posts')
4  .eq('published', true)
5  .like('title', '%guide%')
6  .select('id, title')
7
8// Object form
9const active = await db
10  .from('users')
11  .where({ active: true })
12  .select('id, name')

Modifiers

  • order(column, { ascending?, nullsFirst? })
  • limit(n)
  • range(from, to)
1const recent = await db
2  .from('posts')
3  .order('created_at', { ascending: false })
4  .limit(10)
5  .select('id, title, created_at')

Relational selects (projection strings)

Use nested projection strings to include parent fields.

SQLite adapters today: support “SELECT list + LEFT JOINs for one‑level many‑to‑one nesting.”
Deep chains (a → b → c) or inline 1→M expansions are not executed by the current join builder.

1// Todos with owning user's name (M→1, one level)
2const todos = await db
3  .from('todos')
4  .where({ user_id: 1 })
5  .select('id, title, users(name)')

For deeper/collection expansions, use two queries and compose in code, or DB‑side views.


Types & validation

  • Return types are inferred from your schema and the projection you pass.
  • Adapters validate payloads at runtime; filter columns are checked against known fields.

Summary

Select is compose → then execute: chain filters/modifiers first, then call .select(...). Keep projections tight, use one‑level M→1 nesting on SQLite, and rely on the schema for strong typing across adapters.