Database — Using Filters
Narrow results with a small set of composable operators.
Chain filters on a table, then execute with select().
Prerequisite: You have a client created with a
dbSpec(schema+relations[+ optionalseed,meta]) and an adapter factory for SQLite Web/Expo or Supabase.
Execution Rule
- In v1.0,
.select(projection)executes the query. - Add all filters before calling
.select(...).
How filters combine
- Each filter call adds an AND clause.
- Chain freely:
.eq('published', true).gt('created_at', someDate) - You can also use a single object:
.where({ published: true })
eq(column, value)
Match exact value.
1const users = await db
2 .from('users')
3 .eq('email', 'ada@example.com')
4 .select('id, name, email')ne(column, value)
Not equal.
1const posts = await db
2 .from('posts')
3 .ne('published', true)
4 .select('id, title, published')gt(column, value) / gte(column, value)
Greater than / greater than or equal.
1const cutoff = new Date('2024-01-01')
2const recent = await db
3 .from('posts')
4 .gt('created_at', cutoff) // or .gte('created_at', cutoff)
5 .select('id, title, created_at')lt(column, value) / lte(column, value)
Less than / less than or equal.
1const until = new Date('2024-01-01')
2const older = await db
3 .from('posts')
4 .lt('created_at', until) // or .lte('created_at', until)
5 .select('id, title, created_at')in(column, values[])
Column is one of the provided values.
1const byUsers = await db
2 .from('posts')
3 .in('user_id', [1, 2, 3])
4 .select('id, title, user_id')like(column, pattern)
Case-sensitive pattern match (adapter/DB dependent). % is a wildcard.
1const guides = await db
2 .from('posts')
3 .like('title', '%guide%')
4 .select('id, title')Composing filters (examples)
1// Draft posts for specific users in 2025
2const start = new Date('2025-01-01')
3const results = await db
4 .from('posts')
5 .eq('published', false)
6 .in('user_id', [1, 2])
7 .gte('created_at', start)
8 .select('id, title, user_id, created_at')
9
10// Name search excluding a specific email
11const matches = await db
12 .from('users')
13 .like('name', 'Ada%')
14 .ne('email', 'ada@old.example')
15 .select('id, name, email')Types & validation
- Filtered column names are checked against
dbSpec.schema. - Values should match the column’s inferred TypeScript kind (e.g.,
Datefortimestamp). - Returns typed rows based on your projection.
Adapter notes
- SQLite (Web / Expo): filters run locally against SQLite; ensure your migrations (SQL DDL) align with schema kinds.
- Supabase (bundled in
@vibecode-db/client): filters translate to Postgres via Supabase; ensure columns/types match and RLS permits reads.
Summary
Compose intent with .where(...) and operator helpers, then call .select(...) to execute. Keep projections tight for faster responses and clearer types.