entidb 1.0.1
entidb: ^1.0.1 copied to clipboard
An embedded, entity-based document database for Dart and Flutter with typed collections, indexing, transactions, encryption, and backup support.
EntiDB #
An embedded, entity-based document database for Dart and Flutter applications.
Overview #
EntiDB is a local, entity-based document database written in Dart. You define entity classes that implement a simple interface, and EntiDB handles serialization, storage, and retrieval. It provides typed collections, indexing, transactions, and optional encryption. It works with both Dart CLI applications and Flutter apps.
Features #
- Document Storage - Store and retrieve typed entities with automatic serialization
- Collections - Organize documents into typed collections
- Indexing - BTree, Hash, and Full-Text indexes for query performance
- Query Builder - Build queries with equality, comparison, and logical operators
- Transactions - ACID transactions with configurable isolation levels
- Encryption - Optional AES-GCM encryption for data at rest
- Compression - Reduce storage size with configurable compression
- Migrations - Schema versioning with forward and backward migrations
- Backups - Full, differential, and incremental backup support
- Write-Ahead Log - Crash recovery via WAL
Installation #
Add to your pubspec.yaml:
dependencies:
entidb: ^1.0.0
Then run:
dart pub get
Quick Start #
Define an Entity #
import 'package:entidb/entidb.dart';
class Product implements Entity {
@override
final String? id;
final String name;
final double price;
final int quantity;
Product({
this.id,
required this.name,
required this.price,
required this.quantity,
});
@override
Map<String, dynamic> toMap() => {
'name': name,
'price': price,
'quantity': quantity,
};
static Product fromMap(String id, Map<String, dynamic> map) => Product(
id: id,
name: map['name'] as String,
price: (map['price'] as num).toDouble(),
quantity: map['quantity'] as int,
);
}
Open Database and Use Collections #
import 'package:entidb/entidb.dart';
Future<void> main() async {
// Open database with file storage
final db = await EntiDB.open(
path: './data',
config: EntiDBConfig.production(),
);
// Get a typed collection
final products = await db.collection<Product>(
'products',
fromMap: Product.fromMap,
);
// Insert
final id = await products.insert(
Product(name: 'Widget', price: 29.99, quantity: 100),
);
// Query
final results = await products.find(
QueryBuilder().whereGreaterThan('price', 20.0).build(),
);
// Update
final product = await products.get(id);
if (product != null) {
await products.update(product.copyWith(quantity: 90));
}
// Delete
await products.delete(id);
// Close
await db.close();
}
In-Memory Database #
For testing or temporary data:
final db = await EntiDB.open(
path: null, // null path = in-memory
config: EntiDBConfig.inMemory(),
);
Queries #
EntiDB provides a QueryBuilder for constructing queries:
// Equality
QueryBuilder().whereEquals('status', 'active').build();
// Comparison
QueryBuilder().whereGreaterThan('price', 100.0).build();
QueryBuilder().whereLessThan('quantity', 10).build();
QueryBuilder().whereBetween('price', 50.0, 200.0).build();
// String/List contains
QueryBuilder().whereContains('tags', 'electronics').build();
// Logical operators
QueryBuilder()
.whereEquals('category', 'phones')
.whereGreaterThan('price', 500.0)
.build();
// Or conditions
QueryBuilder()
.whereEquals('status', 'active')
.or(QueryBuilder().whereEquals('featured', true).build())
.build();
Indexes #
Create indexes to speed up queries:
// Hash index for equality lookups
await products.createIndex('category', IndexType.hash);
// BTree index for range queries
await products.createIndex('price', IndexType.btree);
// Full-text index for text search
await products.createIndex('description', IndexType.fullText);
Transactions #
await db.transaction((txn) async {
final products = await txn.collection<Product>('products', fromMap: Product.fromMap);
await products.insert(Product(name: 'Item 1', price: 10.0, quantity: 5));
await products.insert(Product(name: 'Item 2', price: 20.0, quantity: 10));
// Both inserts succeed or both fail
});
Isolation levels:
await db.transaction(
(txn) async { /* ... */ },
isolationLevel: IsolationLevel.serializable,
);
Encryption #
Enable encryption for sensitive data:
final db = await EntiDB.open(
path: './secure_data',
config: EntiDBConfig(
encryption: EncryptionConfig(
enabled: true,
key: yourSecretKey, // 32 bytes for AES-256
),
),
);
Backups #
// Create backup
final backup = db.backup;
await backup.createBackup('./backups/backup_2024.db');
// Restore from backup
await backup.restore('./backups/backup_2024.db');
// Differential backup (only changes since last backup)
await backup.createDifferentialBackup('./backups/diff.db', since: lastBackupTime);
Migrations #
Handle schema changes:
final migration = Migration(
version: 2,
name: 'add_email_field',
up: (db) async {
// Migration logic
},
down: (db) async {
// Rollback logic
},
);
final runner = MigrationRunner(db);
await runner.register(migration);
await runner.migrateToLatest();
Configuration #
final config = EntiDBConfig(
// Storage settings
pageSize: 4096,
cacheSize: 1000,
// Compression
compression: CompressionConfig(enabled: true),
// Query cache
queryCache: QueryCacheConfig(
enabled: true,
maxSize: 100,
ttl: Duration(minutes: 5),
),
// Logging
logLevel: LogLevel.info,
);
Examples #
See the example/ directory for complete examples:
basic_crud.dart- Create, Read, Update, Delete operationsquerying.dart- Query builder usagecollections.dart- Working with collectionspersistence.dart- File-based storageconfiguration.dart- Configuration optionsbenchmark.dart- Performance benchmarks
Run an example:
dart run example/basic_crud.dart
Documentation #
- API Documentation
- Architecture Overview
- API Examples
Limitations #
- Single-process access only (no multi-process locking)
- No built-in replication or clustering
- Full-text search is basic (no stemming, fuzzy matching, or relevance ranking)
- Query optimizer handles simple cases; complex queries may need manual optimization
Testing #
# Run all tests
dart test
# Run with coverage
dart test --coverage=coverage
Contributing #
See CONTRIBUTING.md for guidelines.
License #
MIT License - see LICENSE for details.