persistent_state

Persist state in a Sqlite database across restarts and returns from hibernation


License
MIT

Documentation

Persistent state

pub package

Persist state in an Sqlite database across restarts and returns from hibernation. Powered by Sqlcool

Api

Constructor

PersistentState: constructor parameters:

  • db: an Sqlcool database: see the documentation
  • table: the table to be used for the state. Defailt "state".
  • id: id of the table row to use. Default 1.
  • verbose: verbosity level

Methods

init: initialize the state. Run before using it.

onReady: a future that will complete when the state is initialized

mutate: change the value of a key in the persistent state

  • key: the key to modify
  • value: the new value

This method is asynchronous but can not be awaited. The database queries are queued and will be exectuted in order in case of multiple calls to this method.

select: get the value of a key

  • key: the key to get

This method does not hit the database.

dispose: dispose the state once finished using to clean up memory

describe: prints a description of the state

Example

Goal: to persist the current page

Define the state data and initialize the database

In db.dart:

import 'package:sqlcool/sqlcool.dart';

Db db = Db();

DbTable stateTableSchema() {
  /// Define a state table in the database
  ///
  /// Documentation about schemas:
  /// https://pub.dev/documentation/sqlcool/latest/sqlcool/DbTable-class.html
  ///
  return DbTable("state")..varchar("route", defaultValue: '"/page1"');
}

Future<void> initDb() async {
   try {
      await db.init(
         path: "db.sqlite",
         schema: [stateTableSchema()],
         queries: [_populate()]);
      } catch (e) {
   throw ("Can not init db $e");
   }
}

String _populate() {
   return 'INSERT INTO state(id) VALUES(1)';
}

Create the state

In state.dart:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:persistent_state/persistent_state.dart';
import 'db.dart';

AppState state = AppState();

class AppState {
   PersistentState store;

   Completer _readyCompleter = Completer();

   String get currentRoute => store.select("route");

   Future<dynamic> get onReady => _readyCompleter.future;

   Future<void> navigate(BuildContext context, String routeName) async {
      // Hit the database to update the route
      store.mutate("route", routeName);
      await Navigator.of(context).pushNamed(routeName);
   }

   Future<void> init() async {
      /// db is an Sqlcool [Db] object
      /// run [initDb] before this
      assert(db.isReady);
      try {
         store = PersistentState(db: db);
         store.init();
         await store.onReady;
         _readyCompleter.complete();
      } catch (e) {
         throw ("Can not create persistent state $e");
      }
   }
}

Init state

void main() {
   initDb().then((_) => state.init());
   runApp(MyApp());
}

// later
await state.onReady;
// or
state.onReady.then((_) => doSomething());

Use the state

Calling navigate from anywhere will persist the state of the current route

state.navigate(context, "/page3");