SonicDB

SonicDB is a Flutter library inspired by Android's Room Database, providing a declarative way to build and manage local databases in Flutter apps. It offers type-safe queries, schema migrations, and seamless integration with Flutter's reactive UI. Originally a monolithic project, it has been split into two packages for better modularity:

sonicdb (this package): Flutter-specific integrations, including widgets, platform channels, and UI bindings for easy database operations in Flutter apps. sonicdb_generator: The pure Dart core library for database generation, schema handling, and query utilities. Use this for non-Flutter Dart environments (CLI, server, etc.).

For full details on the generator, visit sonicdb_generator on pub.dev.

Installation

Add the following to your pubspec.yaml:

dependencies:
  sonicdb: ^0.1.0  # Replace with the latest version
  sonicdb_generator: ^0.1.0  # Required for code generation

dev_dependencies:
  build_runner: ^2.4.7  # For running the generator

Then run:

flutter pub get

Prerequisites

  • Flutter SDK ≥ 3.0.0
  • Dart SDK ≥ 3.0.0
  • No additional runtime dependencies beyond standard Flutter packages.

Usage

SonicDB uses code generation to create database classes and DAOs. Annotate your models and DAOs, then run the generator to build the implementation.

1. Define Your Entities

Create Dart classes annotated with @Entity:

App.dart

import 'dart:typed_data';
import 'package:sonicdb_generator/annotation.dart';

part 'App.g.dart';

@Entity(name: "apps")
abstract class App {
  @PrimaryKey(autoGenerated: true)
  @ColumnInfo(name: "_id")
  int id = 0;
  @ColumnInfo(name: "package_name")
  late String packageName = "";
  @ColumnInfo(name: "name")
  late String appName = "";
  @ColumnInfo(name: "day_volume")
  int dayVolume = 0;
  @ColumnInfo(name: "night_volume")
  int nightVolume = 0;
  @ColumnInfo(name: "day_brightness")
  int dayBrightness = 0;
  @ColumnInfo(name: "night_brightness")
  int nightBrightness = 0;
  @ColumnInfo(name: "icon")
  late Uint8List icon;

  factory App({Map? value}) = _App;

  Map toMap();
}

2. Define Collection/DAOs

Create abstract classes for data access:

AppCollection.dart

import 'dart:async';

import 'package:sonicdb_generator/annotation.dart';
import 'package:sonicdb_generator/operation.dart';
import 'package:sonicdb/sonicdb.dart';

@Collection<App>(App)
abstract class AppCollection {
  factory AppCollection(SonicDb db) = _AppCollection;
  late final SonicDb db;
  @Query("select * from apps")
  Future<List<App>> getApps();
  @Query("select * from apps where package_name = :packageName")
  Future<App?> getApp(String packageName);

  @Query("select day_volume from apps where package_name = :packageName")
  Future<int> getDayVolume(String packageName);

  @Update(conditions: ["package_name = :packageName"])
  Future updateDayVolume(String packageName, int dayVolume);

  @Update(conditions: ["package_name = :packageName"])
  Future updateNightVolume(String packageName, int nightVolume);

  @Update(conditions: ["package_name = :packageName"])
  Future updateDayBrightness(String packageName, int dayBrightness);

  @Update(conditions: ["package_name = :packageName"])
  Future updateNightBrightness(String packageName, int nightBrightness);

  @Insert()
  Future add(App app);

  @Insert()
  Future addAll(List<App> apps);
}

3. Define the Database

AppDatabase.dart

import 'package:sonicdb_generator/annotation.dart';
import 'package:sonicdb/sonicdb.dart';

import 'App.dart';
import 'AppCollection.dart';

part 'AppDatabase.g.dart';

@Database(
  name: "varity",
  entities: [App],
  version: 1,
  useDeviceProtectedStorage: true,
)
abstract class AppDatabase extends SonicDb {
  late AppCollection apps;

  static AppDatabase getInstance() {
    return _AppDatabase.getInstance();
  }

  @override
  void onCreate() {
    print("on database created");
  }

  @override
  void onUpgrade() {
    // TODO: implement onUpgrade
    print("on database upgraded");
  }
}

4. Run Code Generation

Execute the build runner:

flutter pub run build_runner build

This generates AppDatabase.g.dart, AppCollection.g.dart and App.g.dart with the concrete implementation.

Acknowledgments

  • Inspired by Android's Room Persistence Library.
  • Thanks to the Dart and Flutter communities for awesome tools like build_runner.

Built with ❤️ for Flutter developers. Questions? Open an issue!

Libraries

sonicdb