Repository
Repositories provide CRUD operations with flexible input handling, accepting tracked models, DTOs, or raw maps.
Snippet context
- Snippets focus on repository calls and omit full setup.
- You can obtain a repository from either:
- a
DataSource/QueryContext(explicit, recommended for multi-database flows), or - the generated model helper class (uses the default connection).
- a
The default connection is tracked by ConnectionManager and is typically set when you call await dataSource.init() (first one auto-defaults) or dataSource.setAsDefault().
Getting a Repository
- Default connection
- From DataSource
Future<void> getRepositoryStaticHelpers() async {
// Assumes a default connection is configured (see DataSource docs).
final userRepo = Users.repo();
await userRepo.find(1);
}
Future<void> getRepositoryExample(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
}
Insert Operations
Insert Single
Future<void> insertExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
// With tracked model
final user = await userRepo.insert(
$User(id: 0, email: 'john@example.com', name: 'John'),
);
// With insert DTO
final user2 = await userRepo.insert(
UserInsertDto(email: 'john@example.com', name: 'John'),
);
// With raw map
final user3 = await userRepo.insert({
'email': 'john@example.com',
'name': 'John',
});
}
Insert Many
Future<void> insertManyExample(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final users = await userRepo.insertMany([
$User(id: 0, email: 'user1@example.com'),
$User(id: 0, email: 'user2@example.com'),
]);
}
Upsert (Insert or Update)
Future<void> upsertExample(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
// Insert if not exists, update if exists
final user = await userRepo.upsert(
$User(id: 1, email: 'john@example.com', name: 'Updated Name'),
);
}
Find Operations
Find by Primary Key
Future<void> findExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final user = await userRepo.find(1); // Returns null if not found
final user2 = await userRepo.findOrFail(1); // Throws if not found
final users = await userRepo.findMany([1, 2, 3]);
}
Get All
Future<void> firstCountExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final user = await userRepo.first();
final user2 = await userRepo.first(where: {'active': true});
final count = await userRepo.count();
final activeCount = await userRepo.count(where: {'active': true});
final hasActive = await userRepo.exists({'active': true});
}
Count & Exists
Future<void> firstCountExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final user = await userRepo.first();
final user2 = await userRepo.first(where: {'active': true});
final count = await userRepo.count();
final activeCount = await userRepo.count(where: {'active': true});
final hasActive = await userRepo.exists({'active': true});
}
Update Operations
Update Single
Future<void> updateExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final user = await userRepo.find(1);
// With tracked model (uses primary key)
if (user != null) {
user.setAttribute('name', 'Updated Name');
final updated = await userRepo.update(user);
}
// With DTO and where clause
final updated2 = await userRepo.update(
UserUpdateDto(name: 'Updated Name'),
where: {'id': 1},
);
// With Query callback
final updated3 = await userRepo.update(
UserUpdateDto(name: 'Updated Name'),
where: (Query<$User> q) => q.whereEquals('email', 'john@example.com'),
);
}
Update Many
Future<void> updateManyExample(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final updated = await userRepo.updateMany([
$User(id: 1, email: 'user1@example.com', name: 'Name 1'),
$User(id: 2, email: 'user2@example.com', name: 'Name 2'),
]);
}
Where Parameter Types
The where parameter accepts various input types:
Future<void> whereTypesExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
// Map
await userRepo.update(UserUpdateDto(name: 'Test'), where: {'id': 1});
// Partial entity
await userRepo.update(
UserUpdateDto(name: 'Test'),
where: $UserPartial(id: 1),
);
// DTO
await userRepo.update(
UserUpdateDto(name: 'Test'),
where: UserUpdateDto(email: 'john@example.com'),
);
// Query callback (must type the parameter!)
await userRepo.update(
UserUpdateDto(name: 'Test'),
where: (Query<$User> q) => q.whereEquals('email', 'test@example.com'),
);
}
Important
When using a callback function for where, you must explicitly type the parameter:
// ✅ Correct - parameter is typed
// where: (Query<$User> q) => q.whereEquals('email', 'test@example.com')
//
// ❌ Wrong - untyped parameter won't work with extension methods
// where: (q) => q.whereEquals('email', 'test@example.com')
Delete Operations
Delete Single
Future<void> deleteExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final user = await userRepo.find(1);
// By primary key
await userRepo.delete(1);
// By tracked model
if (user != null) {
await userRepo.delete(user);
}
// By where clause
await userRepo.delete({'email': 'john@example.com'});
// By Query callback
await userRepo.delete((Query<$User> q) => q.whereEquals('role', 'guest'));
}
Delete Many
Future<void> deleteManyExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
await userRepo.deleteByIds([1, 2, 3]);
await userRepo.deleteMany([
{'id': 1},
(Query<$User> q) => q.whereEquals('role', 'guest'),
]);
}
Soft Delete Operations
For models with SoftDeletes:
Future<void> softDeleteExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final user = await userRepo.find(1);
if (user != null) {
// Soft delete (sets deleted_at)
await userRepo.delete(user);
// Restore
await userRepo.restore(user);
await userRepo.restore({'id': 1});
// Force delete (permanently removes)
await userRepo.forceDelete(user);
}
}
Working with Relations
Future<void> relationExamples(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
final user = await userRepo.find(1);
if (user != null) {
// Load relations
await user.load(['posts', 'profile']);
}
}
Error Handling
Future<void> errorHandlingExample(DataSource dataSource) async {
final userRepo = dataSource.repo<$User>();
try {
final user = await userRepo.findOrFail(999);
} on ModelNotFoundException catch (e) {
print('User not found: ${e.key}');
}
try {
await userRepo.update(UserUpdateDto(name: 'Test'), where: {'id': 999});
} on NoRowsAffectedException {
print('No rows were updated');
}
}