flutter_easy_db 1.1.0
flutter_easy_db: ^1.1.0 copied to clipboard
A secure, easy-to-use encrypted local database for Flutter combining the best of Isar and Drift with AES-256 encryption built in.
flutter_easy_db #
A secure, easy-to-use encrypted local database for Flutter with two modes:
- EasyDbNoSql — Isar-style document database (schema-free, simple put/get/query)
- EasyDbSql — Drift-style relational database (typed tables, joins, foreign keys, migrations)
Both use AES-256 encryption for secure data at rest.
Installation #
dependencies:
flutter_easy_db: ^1.0.0
EasyDbNoSql (Isar-style) #
Schema-free document store. No table definitions needed.
final db = await EasyDbNoSql.open(
EasyDbConfig(
dbName: 'my_app',
encryptionKey: 'my-32-character-secret-key!!!!!', // exactly 32 chars
),
);
final users = db.collection('users');
// Insert
await users.put({'name': 'Alice', 'age': 30});
// Query
final results = await users.query()
.where('age', isGreaterThan: 25)
.where('name', contains: 'li')
.sortBy('age', descending: true)
.limit(10)
.find();
// Watch (reactive)
users.watch().listen((docs) => print('Changed!'));
await db.close();
NoSQL API #
| Method | Description |
|---|---|
collection.put(data, {id}) |
Insert or update a document |
collection.putAll(items) |
Batch insert |
collection.get(id) |
Get by ID |
collection.getAll() |
Get all |
collection.delete(id) |
Delete by ID |
collection.clear() |
Clear collection |
collection.count() |
Count documents |
collection.query() |
Fluent query builder |
collection.watch() |
Reactive stream |
EasyDbSql (Drift-style) #
Typed relational tables with schemas, foreign keys, joins, and migrations.
// Define schemas
final usersSchema = EasyTableSchema(
name: 'users',
columns: [
EasyColumn(name: 'id', type: ColumnType.integer, isPrimaryKey: true, autoIncrement: true),
EasyColumn(name: 'name', type: ColumnType.text),
EasyColumn(name: 'email', type: ColumnType.text, isUnique: true),
EasyColumn(name: 'age', type: ColumnType.integer),
],
);
final postsSchema = EasyTableSchema(
name: 'posts',
columns: [
EasyColumn(name: 'id', type: ColumnType.integer, isPrimaryKey: true, autoIncrement: true),
EasyColumn(name: 'title', type: ColumnType.text),
EasyColumn(name: 'user_id', type: ColumnType.integer,
foreignKey: ForeignKey(referenceTable: 'users', referenceColumn: 'id'),
),
],
);
// Open
final db = await EasyDbSql.open(
EasyDbConfig(dbName: 'my_app', encryptionKey: 'my-32-character-secret-key!!!!!'),
tables: [usersSchema, postsSchema],
);
// Get table — optionally encrypt specific columns
final users = db.table('users', encryptedColumns: ['email']);
// Insert
final userId = await users.insert({'name': 'Alice', 'email': 'alice@example.com', 'age': 30});
// Select with WHERE
final results = await users.select()
.where('age > ?', [25])
.orderBy('name ASC')
.limit(10)
.run();
// JOIN
final joined = await users.select(columns: ['users.name', 'posts.title'])
.join('posts', on: 'users.id = posts.user_id')
.run();
// Update / Delete
await users.update({'age': 31}, where: 'name = ?', whereArgs: ['Alice']);
await users.delete(where: 'name = ?', whereArgs: ['Bob']);
await db.close();
SQL API #
| Method | Description |
|---|---|
table.insert(row) |
Insert a row |
table.insertAll(rows) |
Batch insert |
table.update(values, where:) |
Update matching rows |
table.delete(where:) |
Delete matching rows |
table.deleteAll() |
Delete all rows |
table.count() |
Count rows |
table.select() |
Start a SELECT query |
table.watch() |
Reactive stream |
db.rawQuery(sql) |
Raw SQL query |
db.transaction(fn) |
Run in transaction |
db.addTable(schema) |
Add table at runtime |
db.dropTable(name) |
Drop a table |
SELECT Query Builder #
table.select(columns: ['name', 'age'])
.where('age > ?', [18])
.join('posts', on: 'users.id = posts.user_id')
.leftJoin('comments', on: 'posts.id = comments.post_id')
.orderBy('name ASC')
.limit(20)
.offset(10)
.run(); // List<Map<String, dynamic>>
.runFirst(); // Map<String, dynamic>?
Security #
- AES-256-CBC encryption with SHA-256 key derivation
- NoSQL: entire document encrypted as one blob
- SQL: choose which columns to encrypt (e.g. email, phone)
- Each encryption uses a unique random IV (prevents pattern analysis)
- Key never stored on disk
- Pass
nullforencryptionKeyto disable (dev mode)
Architecture #
┌─────────────────────────────────────────────┐
│ Your Flutter App │
├──────────────────┬──────────────────────────┤
│ EasyDbNoSql │ EasyDbSql │
│ (Isar-style) │ (Drift-style) │
│ put/get/query │ insert/select/join │
├──────────────────┴──────────────────────────┤
│ AES-256 Encryption Layer │
├─────────────────────────────────────────────┤
│ SQLite (sqflite) │
└─────────────────────────────────────────────┘
License #
MIT