tarsier_storage 0.0.4
tarsier_storage: ^0.0.4 copied to clipboard
Package that provides a unified API for working with both local SQLite and remote MySQL databases, enabling seamless switching between offline and online storage.
Tarsier Storage
Documentation • Issues • Example • License • Pub.dev
A unified database abstraction for Flutter & Dart that supports both SQLite (local) and MySQL (remote) with a single API, including backup, restore, progress reporting, and dry-run validation.
Designed for apps that need to seamlessly switch between local and server-based databases without changing business logic.
✨ Features #
- ✅ Unified API for SQLite and MySQL
- ✅ Automatic database type selection
- ✅ Global adapter binding for tables
- ✅ Backup & restore for both databases
- ✅ Progress callbacks for long-running operations
- ✅ Safe restore validation / dry-run
- ✅ ZIP support for SQLite backups
- ✅ Clean, documented, production-ready API
📦 Supported Databases #
| Database | Mode | Backup Format | Restore Validation |
|---|---|---|---|
| SQLite | Local | .bk, .zip |
✅ Yes |
| MySQL | Remote | .sql |
✅ Yes |
🧩 Built on Proven Libraries #
This package does not reinvent database engines.
Instead, it wraps and orchestrates proven, battle-tested libraries to provide a single, hassle-free API.
SQLite Support #
- Powered by
tarsier_local_storagewithsqflite - Uses native SQLite on Android, iOS, macOS, Windows, and Linux
- Handles database creation, table management, and file-based backups
- No additional setup required — already bundled and configured
MySQL Support #
- Powered by
tarsier_mysql_storagewithmysql_client - Supports modern MySQL & MariaDB servers
- Handles connection pooling, query execution, and SQL exports
- Zero boilerplate — configuration is handled internally
Why This Matters #
✅ No need to manually wire multiple database packages
✅ No repetitive setup or configuration code
✅ One consistent API across local and remote databases
✅ Easier onboarding for new developers
✅ Faster project setup and maintenance
This package exists to remove the hassle of database setup, letting you focus on business logic instead of infrastructure.
🚀 Getting Started #
Installation #
dependencies:
tarsier_storage: ^0.0.4
🧠 Database Initialization #
Explicitly validates MySQL vs SQLite intent and by default it requires SQLite when MySQLConfig is not provided
SQLite (Default) #
await TarsierStorage.init(
[UserTable(), OrderTable()],
sqliteDatabaseFile: 'app.db',
);
MySQL #
await TarsierStorage.init(
[UserTable(), OrderTable()],
config: MySQLConfig(
host: 'localhost',
port: 3306,
userName: 'root',
password: 'password',
databaseName: 'app_db',
),
);
📒 Usage #
Define a Model #
Create a class that extends BaseTableModel to represent a database entity:
import 'package:tarsier_storage/tarsier_storage.dart';
class User extends BaseTableModel {
final int? id;
final String name;
final String email;
final DateTime createdAt;
User({this.id, required this.name, required this.email, required this.createdAt});
factory User.fromMap(Map<String, dynamic> map) {
return User(
id: map['id'] as int?,
name: map['name'] as String,
email: map['email'] as String,
createdAt: DateTime.parse(map['created_at'] as String),
);
}
@override
Map<String, dynamic> toMap() {
return {'id': id, 'name': name, 'email': email, 'created_at': createdAt.toIso8601String()};
}
static const String tableName = 'users';
static Map<String, String> schema(DatabaseUse dbUse) {
//@TODO: Should be use via DbColumn annotations
return {
'id': dbUse == DatabaseUse.mysql ? 'INTEGER AUTO_INCREMENT PRIMARY KEY' : 'INTEGER PRIMARY KEY AUTOINCREMENT',
'name': 'TEXT',
'email': 'TEXT',
'created_at': 'TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP',
};
}
}
Define a Table #
Create a table class by extending BaseTable:
import 'package:tarsier_storage/tarsier_storage.dart';
import 'user_model.dart';
class UserTable extends BaseTable<User> {
UserTable()
: super(
tableName: User.tableName,
schema: User.schema(databaseSelector.value),
fromMap: (map) => User.fromMap(map),
toMap: (user) => user.toMap(),
);
@override
Map<String, String> getSchema(DatabaseUse databaseType) {
return User.schema(databaseType);
}
}
Initialize the Database #
Initialize the database and pass the table definitions:
void main() async {
await TarsierStorage.init(
sqliteDatabaseFile: 'app.db', [
UserTable(), // Table class extended by BaseTable
... // Add more table class here
]
);
final userTable = UserTable();
// Add a new user
await userTable.createObject(User(id: 1, name: 'John Doe'));
// Or using Map on creating new user
await userTable.create({
'id' : 1,
'name' : 'John Doe',
});
// Retrieve all users
final users = await userTable.all();
for (var user in users) {
print(user.name);
}
}
💾 Backup #
await TarsierStorage.backup(
path: 'backups/',
archive: true,
onProgress: (current, total, message) => print('$current/$total $message'),
);
🔄 Restore #
await TarsierStorage.restore(
'backups/app_backup.sql',
);
🧪 Restore Validation (Dry-Run) #
/// This does not returns validation result
await TarsierStorage.restore(
'backup.sql',
dryRun: true, // 👈 validation only
);
// or
// It returns validation result
final result = await TarsierStorage.validateRestore('backup.sql');
if (!result.isValid) {
debugPrint('Errors: ${result.errors}');
} else {
debugPrint('Warnings: ${result.warnings}');
}
Screenshots #
| Dashboard | Users | Add / Edit User | Categories |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
| Add / Edit Category | Products | Add / Edit Product | Notes (Grid) |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
| Notes (List) | Add / Edit Note | Backup | Restore |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
🗺️ Roadmap / TODOs #
The following features are planned and tracked for future releases:
🧱 Schema & Migrations #
- ⏳ Annotation-based table definitions
- ⏳ Automatic schema migration system
- ⏳ Versioned database migrations
- ⏳ Migration dry-run & rollback support
🔐 Security #
- ⏳ SQLite password / encryption support (SQLCipher)
- ⏳ Encrypted backup files (AES-256)
- ⏳ Secure key management hooks
📦 Backup Enhancements #
- ⏳ MySQL backup compression (ZIP / GZIP)
- ⏳ Streaming backups for large databases
- ⏳ Incremental backup support
🔍 Validation & Tooling #
- ⏳ Schema diff before restore
- ⏳ Restore preview & impact analysis
- ⏳ Checksum & integrity validation
⚙️ Platform & DX #
- ⏳ Web support (IndexedDB adapter)
- ⏳ CLI tooling for backup & restore
- ⏳ Improved logging & diagnostics
- ⏳ Background / scheduled backups
📄 License #
MIT License











