Database Data Provider
The primary provider for CRUD operations on database tables.
Setup
<Refine dataProvider={dataProvider(client)} resources={[{ name: "posts" }]} />
Return Values
All hooks return { result, query } (for queries) or { mutate, mutation } (for mutations), following Refine v5 conventions.
Query Hooks (useList, useOne, useMany)
const { result, query } = useList({ resource: "posts" });
// result — the resolved data
result.data; // TData[] — array of records
result.total; // number — total record count (for pagination)
// query — TanStack Query state
query.isLoading; // boolean — true during initial fetch
query.isError; // boolean — true if the query failed
query.error; // HttpError | null — error details
query.isRefetching;// boolean — true during background refetch
query.refetch; // () => void — manually re-run the query
const { result, query } = useOne({ resource: "posts", id: 1 });
result.data; // TData — single record object
const { result, query } = useMany({ resource: "posts", ids: [1, 2, 3] });
result.data; // TData[] — array of records
Mutation Hooks (useCreate, useUpdate, useDelete)
const { mutate, mutation } = useCreate();
mutate(
{ resource: "posts", values: { title: "Hello" } },
{
onSuccess: (result) => {
result.data; // TData — the created record
},
onError: (error) => {
error.message; // string
error.statusCode; // number
},
}
);
// mutation — TanStack Query mutation state
mutation.isLoading; // boolean — true while mutating
mutation.isError; // boolean
mutation.isSuccess; // boolean
const { mutate, mutation } = useUpdate();
mutate({
resource: "posts",
id: 1,
values: { title: "Updated" },
});
// onSuccess result.data → the updated record
const { mutate, mutation } = useDelete();
mutate({ resource: "posts", id: 1 });
// onSuccess result.data → the deleted record (if returned by backend)
CRUD Operations
// List records
const { result, query } = useList({ resource: "posts" });
// result.data → IPost[], result.total → number
// query.isLoading, query.isError, query.error
// Get single record
const { result, query } = useOne({ resource: "posts", id: 1 });
// result.data → IPost
// Get multiple records
const { result, query } = useMany({ resource: "posts", ids: [1, 2, 3] });
// result.data → IPost[]
// Create
const { mutate, mutation } = useCreate();
mutate({ resource: "posts", values: { title: "Hello" } });
// mutation.isLoading, mutation.isSuccess, mutation.isError
// Update
const { mutate, mutation } = useUpdate();
mutate({ resource: "posts", id: 1, values: { title: "Updated" } });
// Delete
const { mutate, mutation } = useDelete();
mutate({ resource: "posts", id: 1 });
Filtering
const { result, query } = useList({
resource: "posts",
filters: [
{ field: "status", operator: "eq", value: "published" },
{ field: "views", operator: "gte", value: 100 },
{ field: "title", operator: "contains", value: "refine" },
{ field: "category", operator: "in", value: ["tech", "news"] },
],
});
// result.data → filtered IPost[], result.total → filtered count
Supported filter operators:
| Operator | SDK Mapping | Description |
|---|---|---|
eq | eq | Equal |
ne | ne | Not equal |
lt, gt, lte, gte | lt, gt, lte, gte | Comparison |
contains | contains | Contains (case-sensitive) |
containss | icontains | Contains (case-insensitive) |
startswith | startswith | Starts with (case-sensitive) |
startswiths | istartswith | Starts with (case-insensitive) |
endswith | endswith | Ends with (case-sensitive) |
endswiths | iendswith | Ends with (case-insensitive) |
in | in | In array |
nin | nin | Not in array |
null | isnull | Is null |
Sorting & Pagination
const { result, query } = useList({
resource: "posts",
sorters: [
{ field: "created_at", order: "desc" },
{ field: "title", order: "asc" },
],
pagination: { currentPage: 1, pageSize: 20 },
});
// result.data → sorted/paginated IPost[], result.total → total count
Meta Options
The meta parameter accepts TaruviMeta for Taruvi-specific features:
const { result, query } = useList({
resource: "posts",
meta: {
tableName: "blog_posts", // override table name
populate: ["author", "category"], // populate foreign keys (or "*" for all)
select: ["id", "title", "status"], // select specific fields
idColumnName: "post_id", // custom primary key column
},
});
// result.data → IPost[] with populated author & category objects
| Meta Option | Type | Default | Description |
|---|---|---|---|
tableName | string | resource name | Override the database table name |
populate | string | string[] | — | Foreign key fields to populate. "*" for all |
select | string | string[] | — | Fields to return |
idColumnName | string | "id" | Custom primary key column name |
headers | Record<string, string> | — | Custom request headers |
Aggregations
const { result, query } = useList({
resource: "orders",
meta: {
aggregate: ["sum(total)", "count(*)", "avg(quantity)"],
groupBy: ["status", "category"],
having: [{ field: "sum(total)", operator: "gte", value: 1000 }],
},
});
// result.data → aggregated rows with sum_total, count, avg_quantity fields
Supported aggregate functions: sum, avg, count, min, max, array_agg, string_agg, json_agg, stddev, variance.
Graph Operations
When any graph meta option is present (format, include, depth, graph_types), the provider switches from Database to Graph SDK class.
Reading Graph Data
// Get graph structure for a record
const { result, query } = useOne({
resource: "employees",
id: "1",
meta: {
format: "graph", // "tree" or "graph"
include: "descendants", // "descendants", "ancestors", or "both"
depth: 2,
graph_types: ["manager", "mentor"],
},
});
// result.data → graph/tree structure with nested nodes
// List with graph format
const { result, query } = useList({
resource: "employees",
meta: { format: "tree", include: "both", depth: 3 },
});
// result.data → array of tree-structured records
| Meta Option | Type | Description |
|---|---|---|
format | "tree" | "graph" | Output format |
include | "descendants" | "ancestors" | "both" | Traversal direction |
depth | number | Traversal depth |
graph_types | string[] | Filter edges by type |
Managing Graph Edges
When graph meta is present, mutations operate on edges instead of records:
// Create edge
const { mutate } = useCreate();
mutate({
resource: "employees",
values: { from_id: 1, to_id: 2, type: "manager", metadata: { since: "2024-01-01" } },
meta: { format: "graph" },
});
// Update edge
const { mutate } = useUpdate();
mutate({
resource: "employees",
id: "edge-123",
values: { from_id: 1, to_id: 3, type: "manager" },
meta: { format: "graph" },
});
// Delete edge
const { mutate } = useDelete();
mutate({ resource: "employees", id: "edge-123", meta: { format: "graph" } });
// Delete multiple edges
const { mutate } = useDeleteMany();
mutate({ resource: "employees", ids: ["edge-123", "edge-456"], meta: { format: "graph" } });