Queries
Once data has synced into your app, you can read it from the local database. You have a choice of using the Prisma-inspired client API. Or you can just drop down to raw SQL.
Using the client
The client API supports both static and live queries. Queries are table-scoped. You can select columns, sort, filter and work with relations.
See API -> Typescript client for more details on the function API and supported arguments.
Static queries
Read data using the findUnique
, findFirst
and findMany
functions.
For example, to get a project by unique ID:
const result = await db.projects.findUnique({
where: {
id: 'abcd'
}
})
Or to get all projects that have an 'active' status:
const result = await db.projects.findMany({
where: {
status: 'active'
}
})
Live queries
Register live queries using the liveUnique
, liveFirst
and liveMany
functions.
Live queries work similarly to the static queries above, except that rather than returning results directly, they return a function that you can call (as many times as you like) to run / re-run the query.
const liveQuery = db.projects.liveMany({
where: {
status: 'active'
}
})
const { results } = await liveQuery()
The real payoff comes when these are used in tandem with a reactive component framework integration. For example, the following React component uses a liveMany
query along with the useLiveQuery
hook to bind live results
to a React state variable:
const MyComponent = () => {
const { db } = useElectric()!
const { results } = useLiveQuery(
db.projects.liveMany({
where: {
status: 'active'
}
})
)
// ...
}
See Reacting to writes for more information.
Select columns
Select specific columns using the select
key:
db.projects.liveMany({
select: {
id: true,
status: true
}
})
Sort and filter
Filter results using where
:
db.projects.liveMany({
where: {
status: 'active'
}
})
Where clauses support not
, in
and notIn
operators:
db.projects.liveMany({
where: {
id: {
not: 0,
in: [1, 2, 3],
notIn: [4, 5]
}
}
})
As well as lt
, lte
, gt
and gte
:
db.projects.liveMany({
where: {
id: {
lt: 10,
lte: 9,
gt: 8,
gte: 9
}
}
})
startsWith
, endsWith
and contains
:
db.projects.liveMany({
where: {
name: {
startsWith: 'Electric',
endsWith: 'SQL',
contains: 'cS'
}
}
})
OR
, AND
and NOT
:
db.projects.liveMany({
where: {
OR: [
{
title: {
contains: 'foo',
},
},
{
title: 'bar',
},
],
AND: [
{
contents: 'content',
},
{
nbr: 6,
},
],
NOT: [
{
title: 'foobar',
},
{
title: 'barfoo',
},
]
}
})
Sort results using orderBy
, either with single columns:
db.projects.liveMany({
orderBy: {
id: 'desc'
}
})
Or multiple columns:
db.projects.liveMany({
orderBy: [
{
priority: 'desc'
},
{
createdAt: 'asc'
}
]
})
Limit the number of results using take
:
db.projects.liveMany({
orderBy: {
createdAt: 'desc'
},
take: 10
})
Work with relations
Include a nested tree of relations using include
:
db.projects.liveMany({
include: {
issues: {
include: {
comments: {
include: {
author: true
}
}
}
}
}
})
Raw SQL
If the higher-level client API doesn't support the SQL features that you need for your queries, you can drop down to raw SQL yourself using the raw
and liveRaw
functions.
To run a static query (or just execute SQL):
const projects = db.rawQuery({
sql: 'select * from projects where id = ?',
bindParams: ['abcd']
})
To run a live query that supports arbitrary SQL whilst still working automatically with the reactivity machinery to pick up on live changes:
const liveQuery = db.liveRawQuery({
sql: 'select * from projects where id = ?',
bindParams: ['abcd']
})
const { results } = liveQuery()
For example:
const MyComponent = () => {
const { db } = useElectric()!
const { results } = useLiveQuery(
db.liveRawQuery({
sql: 'select * from projects where status = ?',
bindParams: ['active']
})
)
// ...
}