tarsier_storage 0.0.4 copy "tarsier_storage: ^0.0.4" to clipboard
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

DocumentationIssuesExampleLicensePub.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_storage with sqflite
  • 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_storage with mysql_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
Dashboard Users Add/Edit User Categories
Add / Edit Category Products Add / Edit Product Notes (Grid)
Add/Edit Category Products Add/Edit Product Notes Grid
Notes (List) Add / Edit Note Backup Restore
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

0
likes
140
points
279
downloads

Publisher

unverified uploader

Weekly Downloads

Package that provides a unified API for working with both local SQLite and remote MySQL databases, enabling seamless switching between offline and online storage.

Repository (GitHub)
View/report issues

Topics

#tarsier #storage #sqlite #mysql

Documentation

API reference

License

MIT (license)

Dependencies

archive, flutter, mysql_client, path_provider, sqflite, sqflite_common_ffi, sqflite_common_ffi_web, tarsier_logger, universal_io

More

Packages that depend on tarsier_storage