sembast 1.13.3+1

  • Example
  • Installing
  • Versions
  • 93

sembast.dart #

sembast db stands for Simple Embedded Application Store database

Build Status

General #

Yet another NoSQL persistent store database solution for single process io applications. The whole document based database resides in a single file and is loaded in memory when opened. Changes are appended right away to the file and the file is automatically compacted when needed.

Works on Dart VM and Flutter (no plugin needed, 100% Dart). Inspired from IndexedDB, DataStore, WebSql, NeDB, Lawndart...

Supports encryption using user-defined codec.

Usage #

Opening a database #

A database is a single file represented by a path in the file system

// File path to a file in the same directory than the current script
String dbPath = join(dirname(Platform.script.toFilePath()), "sample.db");
DatabaseFactory dbFactory = databaseFactoryIo;

// We use the database factory to open the database
Database db = await dbFactory.openDatabase(dbPath);

The db object is ready for use.

Simple put/get records #

For quick usage, data can be written and read quickly using the put/get/delete api on the database object

// Easy to put/get simple values or map
// A key can be anything (int, String) as long is it can
// be properly JSON encoded/decoded
await db.put('Simple application', 'title');
await db.put(10, 'version');
await db.put({'offline': true}, 'settings');

// read values
String title = await db.get('title') as String; 
int version = await db.get('version') as int;
Map settings = await db.get('settings') as Map;
// ...and delete
await db.delete('version');

Record fields can be reference using a dot (.).

For example

record['path.sub'] = 1;
// means {'path': {'sub': 1}}

Follow the links with more informatin on how to write or read data

Auto increment #

If no key is provided, the object is inserted with an auto-increment value

// Auto incrementation is built-in
int key1 = await db.put('value1') as int;
int key2 = await db.put('value2') as int;
// key1 = 1, key2 = 2...

Transaction #

Actions can be group in transaction for consistency and optimization (single write on the file system). If an error is thrown, the transaction is cancelled and the changes reverted.

To prevent deadlock, never use an existing Database or Store object.

await db.transaction((txn) async {
  await txn.put('value1');
  await txn.put('value2');

More info on transaction here

Simple wrapping into a Record object #

A record object holds the record content and key

int key = await db.put({'offline': true});
Record record = await db.getRecord(key);
// A record can be accessed like a map
expect(record['offline'], isTrue);
// and has the key in it
expect(record.key, key);

Simple find mechanism #

Filtering and sorting can be done on any field

More information here

// Store some objects
await db.transaction((txn) async {
  await txn.put({'name': 'fish'});
  await txn.put({'name': 'cat'});
  await txn.put({'name': 'dog'});

// Look for any animal "greater than" (alphabetically) 'cat'
// ordered by name
var finder = Finder(
  filter: Filter.greaterThan('name', 'cat'),
  sortOrders: [SortOrder('name')]);
var records = await db.findRecords(finder);

expect(records.length, 2);
expect(records[0]['name'], 'dog');
expect(records[1]['name'], 'fish');

Store #

The store has some similarities with IndexedDB store and DataStore entities. The database always has a main store for easy access (like in the example aboves or typically to save singletons) and allows for an infinite number of stores where a developer would store entity specific data (such as list of record of the same 'type')

// Access the "animal" store
Store animalStore = db.getStore("animal");
// create animals in the store
var cat = Record(animalStore, {'name': 'cat'});
var dog = Record(animalStore, {'name': 'dog'});
// save them
await db.putRecords([cat, dog]);
// get all animals
await animalStore.records.listen((Record animal) {
  // here we know we have a single record
  // .. you'll get dog and cat here

Codec and encryption #

Sembast supports using a user-defined codec to encode/decode data when read/written to disk. It provides a way to support encryption. Encryption itself is not part of sembast but an example of an xxtea based encryption is provided in the test folder:

// Initialize the encryption codec with a user password
var codec = getXXTeaSembastCodec(password: '[your_user_password]');

// Open the database with the codec
Database db = await factory.openDatabase(dbPath, codec: codec);

// ...your database is ready to use as encrypted

More information here

idb_shim #

The project idb_shim provides a shim allowing accessing it using the IndexedDB api. The benefit is to be able to write the logic/synchronization part of the database layer and test its algorithms using Dart VM and not Dartium

// Idb factory based on sembast
var idbFactory = IdbSembastFactory(databaseFactoryIo);

String store = "my_store";

// Here the indexed db API can be used
void _initializeDatabase(VersionChangeEvent e) {
  Database db = e.database;
  // create a store
  ObjectStore objectStore = db.createObjectStore(store);
Database db = await, version: 1, onUpgradeNeeded: _initializeDatabase);

Transaction transaction = db.transaction(store, IDB_MODE_READ_WRITE);
ObjectStore objectStore = transaction.objectStore(store);

// put and read on object
await objectStore.put("value", "test");
expect(await objectStore.getObject("test"), "value");

await transaction.completed;

Information #

Storage format #

Data is stored in a text file where each line is (json format) either:

  • meta information of the database (first line)
  • record data

Each data written is appended to the file for best performance. Compact might happen at any moment to prevent record duplication. The whole compact information is done in a new file followed by a rename to make it atomic.

Supported types #

Supported types depends on JSON supported types. More information here

Keys #

Supported key types are:

  • int (default with autoincrement when no key are passed)
  • String
  • double

Values #

Supported value types are:

  • String.
  • num (int and double)
  • Map
  • List
  • bool
  • null

Build status #

Travis: Build Status

1.13.3 #

  • Add support for user-defined codec to allow encryption

1.13.0 #

  • Add support for nested dotted fields, i.e. 'path.sub' allow setting/getting/filtering/sorting on path inner value sub
  • support for boundaries (start and end) in a query with sort orders

1.12.0 #

  • Add Filter.matchs for regular expression filtering
  • Add rootPath support for DatabaseFactoryIo to allow relative path to a root folder

1.10.1 #

  • Add update method to allow updating partially a Map record
  • Add updateRecords utility methods to update multiple records based on a a filter
  • properly clone each value when written and read

1.9.5 #

  • Fix database manipulation issues during onVersionChanged

1.9.4 #

  • Add value_utils to help comparing value and arrays

1.9.1 #

  • New transaction API
  • dart2 only

1.8.0 #

  • fix flutter cast issue
  • fix limit/offset implementation
  • Update synchronized dependency
  • make all constants lowercase

1.7.0 #

  • mode databaseModeNeverFails is the new default
  • API cleanup and add deprecations

1.6.1 #

  • Add implicit-cast: false support

1.6.0 #

1.5.0 #

  • Update synchronized dependency
  • Add DatabaseMode.NEVER_FAILS that will ignore the file once a corrupted record is encountered

1.3.9 #

  • Add web example to test ddc support
  • Fix transaction

1.3.7 #

  • Strong mode support
  • support for setting record field directly
  • fix support for dart 1.24

1.3.1 #

  • Add support for import/export

1.2.2 #

  • Add for support for isNull and notNull filter
  • Add for support for sorting null last
  • Travis test integration

1.0.0 #

  • Initial revision


// basically same as the io runner but with extra output
import 'dart:async';

import 'package:path/path.dart';
import 'package:sembast/sembast.dart';
import 'package:sembast/sembast_io.dart';

Future main() async {
  Database db = await databaseFactoryIo
      .openDatabase(join(".dart_tool", "sembast", "example", "record_demo.db"));
  Store store = db.getStore("my_store");
  Record record = Record(store, {"name": "ugly"});
  record = await db.putRecord(record);
  record = await store.getRecord(record.key);
  record =
      (await store.findRecords(Finder(filter: Filter.byKey(record.key)))).first;
  record = await store.getRecord(record.key);
  var records =
      (await store.findRecords(Finder(filter: Filter.matches("name", "^ugl"))));

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  sembast: ^1.13.3+1

2. Install it

You can install packages from the command line:

with pub:

$ pub get

with Flutter:

$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:sembast/sembast.dart';
Version Uploaded Documentation Archive
1.13.3+1 Feb 12, 2019 Go to the documentation of sembast 1.13.3+1 Download sembast 1.13.3+1 archive
1.13.3 Feb 8, 2019 Go to the documentation of sembast 1.13.3 Download sembast 1.13.3 archive
1.13.2 Jan 16, 2019 Go to the documentation of sembast 1.13.2 Download sembast 1.13.2 archive
1.13.0 Jan 8, 2019 Go to the documentation of sembast 1.13.0 Download sembast 1.13.0 archive
1.12.0+1 Nov 29, 2018 Go to the documentation of sembast 1.12.0+1 Download sembast 1.12.0+1 archive
1.12.0 Nov 29, 2018 Go to the documentation of sembast 1.12.0 Download sembast 1.12.0 archive
1.11.0 Nov 16, 2018 Go to the documentation of sembast 1.11.0 Download sembast 1.11.0 archive
1.10.2 Nov 16, 2018 Go to the documentation of sembast 1.10.2 Download sembast 1.10.2 archive
1.10.1 Nov 8, 2018 Go to the documentation of sembast 1.10.1 Download sembast 1.10.1 archive
1.10.0 Nov 6, 2018 Go to the documentation of sembast 1.10.0 Download sembast 1.10.0 archive

All 48 versions...

Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Feb 14, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.1.0
  • pana: 0.12.13


Detected platforms: Flutter, web, other

No platform restriction found in primary library package:sembast/sembast.dart.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.58 <3.0.0
logging >=0.11.3 <3.0.0 0.11.3+2
meta >=1.1.6 <3.0.0 1.1.7
path >=1.5.1 <3.0.0 1.6.2
synchronized >=2.0.0 <4.0.0 2.0.2+1
Dev dependencies
build_runner >=0.9.0
build_test >=0.10.2+5
build_web_compilers >=0.4.0+4
dev_test >=0.13.0+3
pedantic >=1.4.0
process_run any
test >=1.5.1
xxtea >=2.0.2