unified_local_data_isar 1.0.0
unified_local_data_isar: ^1.0.0 copied to clipboard
The Isar engine for unified_local_data. Keeps the same storage API on Isar Community, with real transactions and native @collection access.
unified_local_data_isar #
The Isar Community engine for unified_local_data.
Your code keeps using the UnifiedDataSource API (put, get, putObject, watch, query, drop, …) exactly as with Hive. On top of that, Isar gives you:
- Real transactions.
transaction()runs in one Isar write transaction. Every write inside it joins, and if the action throws, all of them roll back. - Your own
@collectionclasses throughnative<T>(), with Isar's indexes and binary speed. - Isar's full query language through
rawInstance, when you need composite indexes or full-text search.
Isar runs on Android, iOS, macOS, Windows and Linux. It doesn't run on the web; use the Hive engine of unified_local_data there.
Installation #
flutter pub add unified_local_data_isar
It depends on unified_local_data and re-exports it, so one import covers both:
import 'package:unified_local_data_isar/unified_local_data_isar.dart';
Usage #
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:unified_local_data_isar/unified_local_data_isar.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final dir = await getApplicationDocumentsDirectory();
final db = await UnifiedDataSourceFactory.create(
IsarDataSourceConfig(directory: dir.path),
);
await db.put<String>('settings', 'theme', 'dark');
final theme = await db.get<String>('settings', 'theme');
}
| Option | Default | Description |
|---|---|---|
directory |
required | Where Isar keeps its database. |
schemas |
[] |
The schemas of your own @collection classes. Not needed for the generic API. |
maxSizeMiB |
256 |
The most the database may grow to. |
inspector |
false |
Enables the Isar Inspector, for debug builds. |
The rest of the API is described in the unified_local_data README.
Transactions #
await db.transaction(() async {
await db.put<int>('cart', 'apples', 3);
await db.delete('cart', 'pears');
await db.native<ProductEntity>('products').put(product);
});
Every data source call inside the action, every write through native<T>(), and a nested transaction() all join the same Isar transaction. If the action throws, every write in it rolls back, and the error reaches the caller unchanged.
Don't call rawInstance.writeTxn() inside transaction(): Isar doesn't nest transactions.
Native @collection access #
Step 1 — Define your Isar model:
import 'package:isar_community/isar.dart';
part 'product_entity.g.dart';
@collection
class ProductEntity {
Id id = Isar.autoIncrement;
@Index()
late String title;
late double price;
@Index(composite: [CompositeIndex('price')])
late String category;
late DateTime createdAt;
}
Add isar_community to your dependencies and isar_community_generator and build_runner to your dev_dependencies.
Step 2 — Run code generation:
dart run build_runner build --delete-conflicting-outputs
Step 3 — Pass the schema and use the collection:
final db = await UnifiedDataSourceFactory.create(
IsarDataSourceConfig(
directory: dir.path,
schemas: [ProductEntitySchema],
),
);
final products = db.native<ProductEntity>('products');
await products.put(
ProductEntity()
..title = 'Flutter Widget'
..price = 29.99
..category = 'Development'
..createdAt = DateTime.now(),
);
final product = await products.getById(1);
products.watchAll().listen((productList) {
print('Products changed: ${productList.length}');
});
final expensive = await products
.query()
.where((p) => p.price > 20.0)
.sortBy((a, b) => b.price.compareTo(a.price))
.limit(5)
.findAll();
query() filters in memory. For indexed queries, use rawInstance.
Raw instance access #
When you need Isar's own query language, with generated .filter(), .sortBy() and composite index queries, use the Isar instance directly:
Future<void> advancedIsarQuery(UnifiedDataSource db) async {
final isar = (db as IsarDataSource).rawInstance;
final results = await isar.productEntitys
.filter()
.categoryEqualTo('Development')
.and()
.priceGreaterThan(10.0)
.sortByPriceDesc()
.limit(20)
.findAll();
}
⚠️ Using
rawInstanceties your code to Isar. Keep it in the repositories where you have chosen Isar on purpose.
How the generic API stores data #
put, putObject and the rest keep every entry, as JSON, in one internal Isar collection, keyed by collection name and key. So:
- Lists come back as
List<dynamic>: read them asList<dynamic>and.cast<T>(). - Maps come back as
Map<String, dynamic>. Store them withputObjectif your code also runs on Hive, where maps read back differently. drop()deletes every entry, or every entry of one collection;clear()does the same for one collection.
Failures are reported as DataSourceReadException and DataSourceWriteException, with Isar's error as cause. native<T>() and rawInstance are Isar itself and throw Isar's errors.
Upgrading from unified_local_data 1.x #
The Isar engine used to be part of unified_local_data. With version 2.0 it moved here:
- Depend on
unified_local_data_isarand importpackage:unified_local_data_isar/unified_local_data_isar.dart. - Replace
UnifiedDataSourceConfig.isar(...)withIsarDataSourceConfig(...).schemasis now optional and typed asList<CollectionSchema<dynamic>>.
The data format is unchanged, so existing databases open as before.
License #
MIT. See LICENSE.