database_bridge 1.0.1 copy "database_bridge: ^1.0.1" to clipboard
database_bridge: ^1.0.1 copied to clipboard

A unified Flutter database service wrapper supporting SQL (Drift, Sqflite), NoSQL (Hive, ObjectBox), and secure storage with a consistent API

database_bridge #

pub package License: MIT

A unified Flutter database service wrapper providing consistent APIs for SQL (Drift, Sqflite), NoSQL (Hive, ObjectBox), and secure storage with comprehensive functionality including encryption, transactions, and reactive streams. This package eliminates the complexity of managing multiple database implementations by offering a single, intuitive interface for all your data persistence needs.


Table of Contents #


Features #

  • Unified API: Consistent method signatures across all database types (SQL, NoSQL, Secure Storage)
  • Multiple Database Support: Hive, Sqflite, Drift, ObjectBox, and Secure Storage in one package
  • Type Safety: Full Dart type safety with generics and compile-time checks (Drift)
  • Encryption: AES encryption for Hive with secure key management via platform-specific secure storage
  • Transactions: ACID-compliant transactions for data integrity across all services
  • Batch Operations: Multiple operations in single atomic transactions
  • Reactive Streams: Real-time data updates and change notifications (Drift)
  • Raw SQL Support: Direct SQL execution when needed (Sqflite, Drift)
  • Aggregations: Built-in statistical functions (count, sum, avg, min, max)
  • Advanced Querying: Complex filters, sorting, pagination, and grouping
  • Cross-Platform: Native support for iOS, Android, Web, and Desktop
  • Error Handling: Comprehensive DatabaseBridgeException with detailed error information

Installation #

dependencies:
  database_bridge: ^1.0.0
flutter pub get

Quick Start #

import 'package:database_bridge/database_bridge.dart';

// Initialize and use Hive for simple key-value storage
final hive = DatabaseBridgeHiveService();
await hive.initializeDatabase();
await hive.write('users', 'john', {'name': 'John', 'age': 30});
final user = await hive.read('users', 'john');

Usage #

Hive (NoSQL with Encryption) #

Fast key-value storage with optional AES encryption support for secure data persistence.

Basic Operations:

final hive = DatabaseBridgeHiveService();
await hive.initializeDatabase();

// Write and read data
await hive.write('users', 'john', {'name': 'John', 'age': 30});
final user = await hive.read('users', 'john'); // Returns Map or defaultValue

// Batch operations
await hive.writeMultiple('users', {
  'jane': {'name': 'Jane', 'age': 25},
  'bob': {'name': 'Bob', 'age': 35}
});

// Check existence and delete
final exists = await hive.hasProperty('users', 'john');
await hive.delete('users', 'john');

Encryption Setup:

// Set up encryption for sensitive data
final security = DatabaseBridgeHiveSecurity();
await security.generateAndSaveSecureKeyIfNotExist();
final cipher = await security.readEncryptionCipher();

// Note: Encryption is typically handled at the Hive box level
// The DatabaseBridgeHiveSecurity class manages the encryption keys
// that can be used with standard Hive boxes for encryption

Sqflite (SQL Database) #

Full-featured SQLite database with raw SQL support, aggregations, and advanced querying capabilities.

Database Setup and Basic CRUD:

final sqlite = DatabaseBridgeSqfliteService(databaseFileName: 'app.db');

await sqlite.openSqliteDatabase(
  databaseVersion: 1,
  onCreate: (db, version) async {
    await db.execute('''
      CREATE TABLE users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        age INTEGER,
        email TEXT UNIQUE
      )
    ''');
  }
);

// CRUD Operations
await sqlite.insert('users', {
  'name': 'John Doe',
  'age': 30,
  'email': 'john@example.com'
});

final users = await sqlite.read('users', where: 'age > ?', whereArgs: [18]);
await sqlite.update('users', {'age': 31}, where: 'name = ?', whereArgs: ['John Doe']);
await sqlite.delete('users', where: 'age < ?', whereArgs: [21]);

Raw SQL and Aggregations:

// Raw SQL queries
final result = await sqlite.rawQuery('SELECT * FROM users WHERE age > ?', [21]);
await sqlite.rawInsert('INSERT INTO users (name, age) VALUES (?, ?)', ['Alice', 25]);

// Built-in aggregations
final userCount = await sqlite.countRows('users');
final avgAge = await sqlite.avg('users', 'age');
final totalAge = await sqlite.sum('users', 'age');
final oldestUser = await sqlite.max('users', 'age');

// Complex aggregations with grouping
final ageStats = await sqlite.aggregateQuery(
  'users',
  groupBy: ['age'],
  aggregations: {'count': 'COUNT(*)'},
  having: 'COUNT(*) > 1'
);

Drift (Type-Safe SQL) #

Advanced SQL with compile-time type safety, reactive streams, and complex querying using Drift ORM.

Basic Type-Safe Operations:

// Assuming you have a Drift database setup
final drift = DatabaseBridgeDriftService(myDatabase);

// Type-safe CRUD operations
final newUser = UsersCompanion(name: Value('John'), age: Value(30));
await drift.insert<UsersTable, User>(newUser);

final users = await drift.getAll<UsersTable, User>();
final adultUsers = await drift.getWithComplexFilter<UsersTable, User>([
  usersTable.age.isBiggerThanValue(18)
]);

Reactive Queries:

// Reactive streams for real-time UI updates
drift.watchAll<UsersTable, User>().listen((users) {
  // Update UI when data changes
  setState(() => userList = users);
});

// Filtered reactive queries
drift.watchFiltered<UsersTable, User>(
  (table) => table.age.isBiggerThanValue(21) & table.name.like('%John%')
).listen((filteredUsers) {
  print('Filtered users: ${filteredUsers.length}');
});

Advanced Querying and Aggregations:

// Complex filtering with multiple conditions
final complexUsers = await drift.getWithSorting<UsersTable, User>(
  [(table) => OrderingTerm.desc(table.age)],
  filter: (table) => table.age.isBetweenValues(20, 40)
);

// Pagination
final page1 = await drift.getPaged<UsersTable, User>(
  limit: 10,
  offset: 0,
  orderBy: [(table) => OrderingTerm.asc(table.name)]
);

// Aggregations
final totalUsers = await drift.count<UsersTable, User>();
final avgAge = await drift.avg<UsersTable, User>('age');
final ageStats = await drift.aggregateWithGroupBy<UsersTable, User>(
  groupByColumns: ['department'],
  aggregations: {'avg_age': 'AVG(age)', 'count': 'COUNT(*)'}
);

ObjectBox (High-Performance NoSQL) #

ACID-compliant object database with advanced querying capabilities and high-performance operations.

Basic Object Operations:

final objectBox = DatabaseBridgeObjectboxService();
await objectBox.initializeStore();

// Your entity classes would be annotated with @Entity
final user = User(name: 'John', age: 30); // Your ObjectBox entity

final userId = await objectBox.put(user);
final retrievedUser = await objectBox.get<User>(userId);
final allUsers = await objectBox.getAll<User>();

Advanced Querying:

// Query with conditions
final adults = await objectBox.query<User>(
  User_.age.greaterThan(18),
  orderBy: User_.name,
  limit: 50
);

final firstAdult = await objectBox.queryFirst<User>(
  User_.age.greaterThan(21) & User_.name.startsWith('J')
);

// Count with conditions
final adultCount = await objectBox.queryCount<User>(
  User_.age.greaterThan(18)
);

Batch Operations and Transactions:

// Batch operations
final userIds = await objectBox.putMany<User>([
  User(name: 'Alice', age: 25),
  User(name: 'Bob', age: 30),
  User(name: 'Charlie', age: 35)
]);

await objectBox.removeMany<User>([userIds[0], userIds[1]]);

// Transaction for atomic operations
await objectBox.runInTransaction(() {
  objectBox.put(User(name: 'Transaction User 1'));
  objectBox.put(User(name: 'Transaction User 2'));
  // If any operation fails, all are rolled back
});

Secure Storage #

Encrypted key-value storage for sensitive data using platform-specific secure storage solutions.

Basic Secure Operations:

final secure = DatabaseBridgeSecureStorageService();
await secure.initialize();

// Store sensitive data
await secure.write('api_key', 'your_secret_api_key');
await secure.write('auth_token', 'jwt_token_here');

// Batch write multiple values
await secure.writeBatch({
  'refresh_token': 'refresh_jwt',
  'user_id': '12345'
});

// Read data
final apiKey = await secure.read('api_key');
final allData = await secure.readAll();

// Check existence and cleanup
final hasApiKey = await secure.containsKey('api_key');
await secure.delete('api_key');
await secure.deleteAll();

API Reference #

Classes #

DatabaseBridgeException

Unified exception class for handling database errors across all services.

const DatabaseBridgeException({this.error});

Properties

Property Type Description
error dynamic The original error that caused this exception

JobDone

Success confirmation class returned by operations that don't return meaningful data. This class serves as a semantic indicator that an operation completed successfully without providing specific return values.

const JobDone();

DatabaseBridgeHiveService

Service for Hive NoSQL database operations with optional encryption support.

factory DatabaseBridgeHiveService();

Methods

Method Returns Description
initializeDatabase() Future<JobDone> Initialize the Hive database
closeDatabase() Future<JobDone> Close the database
openBox(String boxName) Future<Box<dynamic>> Open a Hive box
closeBox(String boxName) Future<JobDone> Close a specific box
write(String boxName, String key, dynamic value) Future<JobDone> Write a single key-value pair
writeMultiple(String boxName, Map<dynamic, dynamic> entries) Future<JobDone> Write multiple key-value pairs
read(String boxName, String key, {dynamic defaultValue}) Future<dynamic> Read a value by key
update(String boxName, String key, dynamic value) Future<JobDone> Update an existing value
addOrUpdate(String boxName, String key, dynamic value) Future<JobDone> Add or update a value
delete(String boxName, String key) Future<JobDone> Delete a single key
deleteMultiple(String boxName, Iterable<dynamic> keys) Future<JobDone> Delete multiple keys
clearBox(String boxName) Future<int> Clear all data in a box
deleteBoxFromDisk(String boxName) Future<JobDone> Delete a box from disk
deleteDatabaseFromDisk() Future<JobDone> Delete the entire database
hasProperty(String boxName, String key) Future<bool> Check if a key exists
registerAdapter<T>(TypeAdapter<T> adapter, {bool override}) Future<JobDone> Register a type adapter

DatabaseBridgeHiveSecurity

Handles AES encryption key management for Hive using secure storage.

DatabaseBridgeHiveSecurity();

Methods

Method Returns Description
generateAndSaveSecureKeyIfNotExist() Future<void> Generate and save encryption key if it doesn't exist
readEncryptionCipher() Future<HiveCipher> Read the encryption cipher for data encryption
deleteSecureKey() Future<void> Delete the stored encryption key

DatabaseBridgeSqfliteService

Service for SQLite database operations via Sqflite with full SQL support.

factory DatabaseBridgeSqfliteService({
  required String databaseFileName,
  ConflictAlgorithm defaultConflictAlgorithm,
});

Methods

Method Returns Description
openSqliteDatabase({int databaseVersion, OnCreate onCreate, OnUpgrade onUpgrade, OnDowngrade onDowngrade, bool readOnly}) Future<JobDone> Open/create SQLite database
closeSqliteDatabase() Future<JobDone> Close the database
deleteSqliteDatabase() Future<JobDone> Delete the database file
read(String table, {bool? distinct, List<String>? columns, String? where, List<Object?>? whereArgs, String? groupBy, String? having, String? orderBy, int? limit, int? offset}) Future<List<Map<String, Object?>>> Query table data
readFirst(String table, {...}) Future<Map<String, Object?>> Get first row from query
insert(String table, Map<String, Object?> values, {String? nullColumnHack, ConflictAlgorithm conflictAlgorithm}) Future<bool> Insert row (returns success)
update(String table, Map<String, Object?> values, {String? where, List<Object?>? whereArgs, ConflictAlgorithm? conflictAlgorithm}) Future<bool> Update rows (returns success)
delete(String table, {String? where, List<Object?>? whereArgs}) Future<bool> Delete rows (returns success)
rawQuery(String sql, [List<Object?>? arguments]) Future<List<Map<String, Object?>>> Execute raw SQL query
rawInsert(String sql, [List<Object?>? arguments]) Future<int> Execute raw insert
rawUpdate(String sql, [List<Object?>? arguments]) Future<int> Execute raw update
rawDelete(String sql, [List<Object?>? arguments]) Future<int> Execute raw delete
excuteRawQuery(String sql, [List<Object?>? arguments]) Future<JobDone> Execute raw query without return
countRows(String table) Future<int> Count all rows in table
count(String table, {String? where, List<Object?>? whereArgs}) Future<int> Count rows with conditions
sum(String table, String column, {String? where, List<Object?>? whereArgs}) Future<double?> Sum column values
avg(String table, String column, {String? where, List<Object?>? whereArgs}) Future<double?> Average column values
min(String table, String column, {String? where, List<Object?>? whereArgs}) Future<Object?> Minimum column value
max(String table, String column, {String? where, List<Object?>? whereArgs}) Future<Object?> Maximum column value
aggregateQuery(String table, {required List<String> groupBy, required Map<String, String> aggregations, String? where, List<Object?>? whereArgs, String? having, String? orderBy, int? limit, int? offset}) Future<List<Map<String, Object?>>> Complex aggregation queries
transaction<T>(Future<T> Function(Transaction txn) action) Future<T> Execute in transaction
executeBatch(void Function(SqfliteBatch batch) operations, {bool? exclusive, bool? noResult, bool? continueOnError}) Future<List<Object?>> Execute batch operations

DatabaseBridgeDriftService

Type-safe SQL service using Drift ORM with reactive capabilities.

factory DatabaseBridgeDriftService(GeneratedDatabase database);

Methods

Method Returns Description
getAll<T extends Table, D>() Future<List<D>> Get all records
getSingle<T extends Table, D>(Expression<bool> Function(T) filter) Future<D?> Get single record
insert<T extends Table, D>(Insertable<D> entity, {InsertMode mode, UpsertClause<T, D>? onConflict}) Future<int> Insert record
update<T extends Table, D>(Insertable<D> entity) Future<bool> Update record
delete<T extends Table, D>(Expression<bool> Function(T) filter) Future<int> Delete records
closeDatabase() Future<void> Close the database
batchInsert<T extends Table, D>(List<Insertable<D>> entities, {InsertMode mode, UpsertClause<T, D>? onConflict}) Future<List<int>> Batch insert
batchUpdate<T extends Table, D>(List<Insertable<D>> entities) Future<List<bool>> Batch update
batchDelete<T extends Table, D>(Expression<bool> Function(T) filter) Future<int> Batch delete
executeBatch(List<BatchOperation> operations) Future<void> Execute batch operations
watchAll<T extends Table, D>() Stream<List<D>> Reactive stream of all records
watchFiltered<T extends Table, D>(Expression<bool> Function(T) filter) Stream<List<D>> Reactive filtered stream
watchSingle<T extends Table, D>(Expression<bool> Function(T) filter) Stream<D?> Reactive single record stream
transaction<R>(Future<R> Function() action) Future<R> Execute in transaction
customSelect<T>(String query, {List<Variable<Object>>? variables}) Future<List<T>> Custom select query
customUpdate(String query, {List<Variable<Object>>? variables}) Future<int> Custom update query
customInsert(String query, {List<Variable<Object>>? variables}) Future<int> Custom insert query
customStatement(String query, {List<Variable<Object>>? variables}) Future<void> Custom SQL statement
getWithComplexFilter<T extends Table, D>(List<Expression<bool>> filters, {bool andLogic}) Future<List<D>> Complex filtering
getIn<T extends Table, D>(Expression column, List<Object?> values) Future<List<D>> IN clause queries
getLike<T extends Table, D>(Expression<String> column, String pattern) Future<List<D>> LIKE queries
getFirstWhere<T extends Table, D>(List<Expression<bool>> conditions, {bool andLogic}) Future<D?> Get first matching record
getWithSorting<T extends Table, D>(List<OrderingTerm Function(T)> orderBy, {Expression<bool> Function(T)? filter, int? limit, int? offset}) Future<List<D>> Sorted queries
getPaged<T extends Table, D>({Expression<bool> Function(T)? filter, List<OrderClauseGenerator<T>>? orderBy, required int limit, required int offset}) Future<List<D>> Paginated queries
getLimited<T extends Table, D>(int limit, {Expression<bool> Function(T)? filter, List<OrderClauseGenerator<T>>? orderBy}) Future<List<D>> Limited result queries
getFirstSorted<T extends Table, D>(List<OrderingTerm Function(T)> orderBy, {Expression<bool> Function(T)? filter}) Future<D?> Get first sorted record
count<T extends Table, D>({Expression<bool>? filter}) Future<int> Count records
sum<T extends Table, D>(String columnName, {Expression<bool>? filter}) Future<double?> Sum column values
avg<T extends Table, D>(String columnName, {Expression<bool>? filter}) Future<double?> Average column values
min<T extends Table, D>(String columnName, {Expression<bool>? filter}) Future<Object?> Minimum column value
max<T extends Table, D>(String columnName, {Expression<bool>? filter}) Future<Object?> Maximum column value
aggregateWithGroupBy<T extends Table, D>({required List<String> groupByColumns, required Map<String, String> aggregations, Expression<bool>? filter, String? having}) Future<List<Map<String, Object?>>> Grouped aggregations

DatabaseBridgeObjectboxService

High-performance NoSQL object database service.

factory DatabaseBridgeObjectboxService({
  Directory? storeDirectory,
  Future<Store> Function(String directory)? storeFactory,
});

Methods

Method Returns Description
initializeStore() Future<JobDone> Initialize ObjectBox store
closeStore() Future<JobDone> Close the store
get<T>(int id) Future<T?> Get object by ID
getAll<T>() Future<List<T>> Get all objects
put<T>(T object) Future<int> Insert or update object
putMany<T>(List<T> objects) Future<List<int>> Batch insert/update
remove<T>(int id) Future<bool> Remove object by ID
removeMany<T>(List<int> ids) Future<int> Remove multiple objects
removeAll<T>() Future<int> Remove all objects
contains<T>(int id) Future<bool> Check if object exists
count<T>() Future<int> Count objects
query<T>(Condition<T>? condition, {QueryProperty<T, dynamic>? orderBy, int? flags, int? offset, int? limit}) Future<List<T>> Query with conditions
queryFirst<T>(Condition<T>? condition, {QueryProperty<T, dynamic>? orderBy, int? flags}) Future<T?> Get first query result
queryCount<T>(Condition<T>? condition) Future<int> Count query results
runInTransaction<R>(R Function() action) Future<R> Execute in transaction
clearAllData() Future<JobDone> Clear all data
compact() Future<JobDone> Compact database
isStoreOpen() bool Check if store is open
store Store? Direct access to ObjectBox store

DatabaseBridgeSecureStorageService

Encrypted key-value storage service using platform secure storage.

factory DatabaseBridgeSecureStorageService();

Methods

Method Returns Description
initialize() Future<JobDone> Initialize secure storage
write(String key, String value) Future<void> Write encrypted value
writeBatch(Map<String, String> data) Future<void> Write multiple encrypted values
read(String key) Future<String?> Read encrypted value
containsKey(String key) Future<bool> Check if key exists
readAll() Future<Map<String, String>> Read all encrypted data
getKeys() Future<List<String>> Get all keys
delete(String key) Future<void> Delete encrypted value
deleteAll() Future<void> Delete all encrypted data

Typedefs #

SqfliteBatch

typedef SqfliteBatch = Batch;

Represents a Sqflite batch operation for grouping multiple database operations.

OnCreate

typedef OnCreate = FutureOr<void> Function(Database, int)?;

Callback function for database creation, receives the database instance and version.

OnUpgrade

typedef OnUpgrade = FutureOr<void> Function(Database, int, int)?;

Callback function for database upgrade, receives database, old version, and new version.

OnDowngrade

typedef OnDowngrade = FutureOr<void> Function(Database, int, int)?;

Callback function for database downgrade, receives database, old version, and new version.

BatchOperation

typedef BatchOperation = void Function(Batch batch);

Function type for Drift batch operations, receives a Batch instance to add operations to.


Complete Examples #

Multi-Service Application #

This example demonstrates using multiple database services in a single Flutter application.

Note: The examples assume you have defined the necessary entity classes (like UserProfile) with appropriate annotations for ObjectBox and Drift. The focus is on showing how to use the database bridge services together.

import 'package:database_bridge/database_bridge.dart';

class DataManager {
  late final DatabaseBridgeHiveService _hive;
  late final DatabaseBridgeSqfliteService _sqlite;
  late final DatabaseBridgeSecureStorageService _secure;
  late final DatabaseBridgeObjectboxService _objectBox;

  Future<void> initialize() async {
    // Initialize all services
    _hive = DatabaseBridgeHiveService();
    await _hive.initializeDatabase();

    _sqlite = DatabaseBridgeSqfliteService(databaseFileName: 'app_data.db');
    await _sqlite.openSqliteDatabase(
      databaseVersion: 1,
      onCreate: (db, version) async {
        await db.execute('''
          CREATE TABLE user_preferences (
            id INTEGER PRIMARY KEY,
            user_id TEXT UNIQUE,
            theme TEXT DEFAULT 'light',
            notifications_enabled INTEGER DEFAULT 1
          )
        ''');
      }
    );

    _secure = DatabaseBridgeSecureStorageService();
    await _secure.initialize();

    _objectBox = DatabaseBridgeObjectboxService();
    await _objectBox.initializeStore();
  }

  // Use Hive for app configuration
  Future<void> saveAppConfig(Map<String, dynamic> config) async {
    await _hive.write('config', 'app_settings', config);
  }

  // Use Sqflite for user preferences
  Future<void> saveUserPreferences(String userId, Map<String, dynamic> prefs) async {
    await _sqlite.insert('user_preferences', {
      'user_id': userId,
      'theme': prefs['theme'],
      'notifications_enabled': prefs['notifications'] ? 1 : 0,
    });
  }

  // Use Secure Storage for sensitive data
  Future<void> saveAuthToken(String token) async {
    await _secure.write('auth_token', token);
  }

  // Use ObjectBox for complex objects
  Future<void> saveUserProfile(UserProfile profile) async {
    await _objectBox.put(profile);
  }

  // Combined data retrieval
  Future<Map<String, dynamic>> getUserData(String userId) async {
    final config = await _hive.read('config', 'app_settings');
    final prefs = await _sqlite.readFirst(
      'user_preferences',
      where: 'user_id = ?',
      whereArgs: [userId]
    );
    final token = await _secure.read('auth_token');
    final profile = await _objectBox.queryFirst<UserProfile>(
      UserProfile_.userId.equals(userId)
    );

    return {
      'config': config,
      'preferences': prefs,
      'hasAuthToken': token != null,
      'profile': profile,
    };
  }
}

Transaction Management #

Demonstrates comprehensive transaction handling across different database services.

import 'package:database_bridge/database_bridge.dart';

class TransactionExample {
  final DatabaseBridgeSqfliteService _sqlite;
  final DatabaseBridgeObjectboxService _objectBox;
  final DatabaseBridgeDriftService _drift;

  TransactionExample(this._sqlite, this._objectBox, this._drift);

  // Sqflite transaction with rollback capability
  Future<bool> transferFunds(String fromAccount, String toAccount, double amount) async {
    try {
      return await _sqlite.transaction((txn) async {
        // Check balance
        final fromBalance = await txn.rawQuery(
          'SELECT balance FROM accounts WHERE id = ?',
          [fromAccount]
        );

        if (fromBalance.isEmpty || fromBalance.first['balance'] < amount) {
          throw DatabaseBridgeException(error: 'Insufficient funds');
        }

        // Perform transfer
        await txn.rawUpdate(
          'UPDATE accounts SET balance = balance - ? WHERE id = ?',
          [amount, fromAccount]
        );

        await txn.rawUpdate(
          'UPDATE accounts SET balance = balance + ? WHERE id = ?',
          [amount, toAccount]
        );

        // Log transaction
        await txn.rawInsert(
          'INSERT INTO transactions (from_account, to_account, amount, timestamp) VALUES (?, ?, ?, ?)',
          [fromAccount, toAccount, amount, DateTime.now().toIso8601String()]
        );

        return true;
      });
    } catch (e) {
      print('Transaction failed: $e');
      return false;
    }
  }

  // ObjectBox transaction for complex object operations
  Future<void> updateUserWithRelatedData(User user, List<Post> posts) async {
    await _objectBox.runInTransaction(() {
      // Update user
      _objectBox.put(user);

      // Update related posts
      for (final post in posts) {
        post.author.target = user; // Set relation
        _objectBox.put(post);
      }

      // Update user stats
      final userStats = UserStats(userId: user.id, postCount: posts.length);
      _objectBox.put(userStats);
    });
  }

  // Drift batch operations
  Future<void> bulkUserUpdate(List<UserUpdate> updates) async {
    await _drift.executeBatch(updates.map((update) {
      return (batch) {
        batch.update(
          _drift.usersTable,
          UsersCompanion(
            name: Value(update.newName),
            email: Value(update.newEmail),
          ),
          where: (table) => table.id.equals(update.userId)
        );
      };
    }).toList());
  }

  // Cross-service transaction simulation
  Future<bool> createUserAccount(User user, String initialPassword) async {
    try {
      // Store user profile in ObjectBox
      final userId = await _objectBox.put(user);

      // Store credentials securely
      await DatabaseBridgeSecureStorageService()
          .write('password_$userId', initialPassword);

      // Create user preferences in Sqflite
      await _sqlite.insert('user_preferences', {
        'user_id': user.id.toString(),
        'theme': 'light',
        'notifications_enabled': 1,
      });

      return true;
    } catch (e) {
      // Cleanup on failure
      await _objectBox.remove<User>(user.id);
      await DatabaseBridgeSecureStorageService().delete('password_${user.id}');
      await _sqlite.delete('user_preferences',
          where: 'user_id = ?', whereArgs: [user.id.toString()]);

      throw DatabaseBridgeException(error: 'Failed to create user account: $e');
    }
  }
}

// Supporting classes for the example
class UserUpdate {
  final int userId;
  final String newName;
  final String newEmail;

  UserUpdate(this.userId, this.newName, this.newEmail);
}

License #

MIT License

Copyright (c) 2026 Mustafa Fahimi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Made with ❤️ by Mustafa Fahimi

2
likes
140
points
0
downloads

Publisher

unverified uploader

Weekly Downloads

A unified Flutter database service wrapper supporting SQL (Drift, Sqflite), NoSQL (Hive, ObjectBox), and secure storage with a consistent API

Repository (GitHub)
View/report issues

Topics

#database #flutter #sql #nosql #storage

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

drift, drift_flutter, flutter, flutter_secure_storage, hive, hive_flutter, objectbox, objectbox_flutter_libs, path, path_provider, sqflite, sqflite_common_ffi, sqflite_common_ffi_web

More

Packages that depend on database_bridge