yomp_db 0.9.1
Yomp DB - pure DART implementation of database with graph querying and replication support. Stores data in IndexedDB or in memory.
NOSQL database engine, with complex queries, event sourcing and replication support. Library has abstract storage mechanism. There are included storages for IndexedDB and pure memory.
See test folder for a lot of examples of usage.
Example use:
import 'package:yomp_db/yomp_db.dart' as ydb;
import "package:yomp_db/storages/indexeddb.dart" as ydb_idb;
...
ydb.Database db = new ydb.Database(new ydb_idb.StorageIndexedDB());
// create a new database named "yompdbsample" with version 1,
// with one store "cities" without indexes
await db.open("yompdbsample", 1, {"cities":[]});
// put several documents in
await db.putSingle("cities",
{"name":"New York","country":"USA"});
String docid = await db.putSingle("cities",
{"name":"Paris","country":"France","capital":"yes"});
await db.putSingle("cities",
{"name":"Bordeaux","country":"France"});
// get object based on ID generated by yomp_db
Map obj = await db.getSingle("cities", docid);
expect(obj["name"],"Paris");
// close the database
await db.close();
QUERY
Library provides string based queries, which are used for get and del. Null string means everything.
Format
BASIC SAMPLE DESRIPTION
id iuh658hUt8 select document via _id property
property = value city = Děčín property equals to value
property != value city != Děčín property doesn't equal to value
!property !capital property missing, is equal to null
It's possible to setup query with multiple conditions, those conditions are divided by comma. Example:
continent = Europe , capital = true which selects all capitals inside Europe. Spaces around condition
and comma are mandatory.
Sample
// get records for query -> country == France && capital == yes
String q = "country = France , capital = yes";
List<Map> result = await db.get("cities",q).toList();
// we expect one result Paris
expect(result.length,1);
expect(result.first["name"],"Paris");
PERFORMANCE
The following result is in miliseconds so the number 7.789 means 7 miliseconds and 789 microseconds. Every query is run against two types of storage, IndexedDB non-indexed and fully indexed, in-Memory non-indexed and fully indexed. My data around rock bands ~ 100 records:
-IDB--- / -IDB-I- / -MEM--- / -MEM-I- : command
0.623 / 0.577 / 0.065 / 0.060 : IRONS
7.451 / 0.606 / 0.067 / 0.059 : name = Queen
7.395 / 0.845 / 0.073 / 0.068 : id_genre = METAL
8.189 / 3.433 / 0.275 / 0.261 : type = album
9.595 / 10.368 / 0.690 / 0.666 : type != album
8.122 / 7.920 / 0.071 / 0.066 : type = person , name = Steve Harris
8.695 / 4.057 / 0.234 / 0.235 : type = person , name != Steve Harris
10.953 / 10.917 / 0.886 / 0.879 : !born_as
8.034 / 1.075 / 0.086 / 0.078 : !born_as , type = band
More interestingly few queries in 1000 fortune companies data set:
-IDB--- / -IDB-I- / -MEM--- / -MEM-I- : command
187.300 / 1.000 / 0.400 / 0.100 : NAME = Google
190.000 / 2.300 / 0.700 / 0.100 : PLACE = Mountain View
203.700 / 27.700 / 2.600 / 1.900 : STATE = CA
287.300 / 285.800 / 15.500 / 15.000 : STATE != CA
199.600 / 33.900 / 2.000 / 1.800 : STATE = CA , PLACE != Mountain View
EVENT SOURCING
yomp_db provides derived class for creating and changing data via events.
ydb.DatabaseES db = new ydb.DatabaseES(new ydb_idb.StorageIndexedDB());
await db.addEvents("cities",[{"id":"DECIN","name":"Děčín"}]);
await db.addEvents("cities",[{"id":"DECIN","country":"Czech Republic"}]);
await db.addEvents("cities",[{"id":"DECIN","+districts":"Bynov"}]);
await db.addEvents("cities",[{"id":"DECIN","+districts":"Boletice"}]);
List ls = await db.get("cities").toList();
// ls contains one object which looks:
{ "_id":"DECIN",
"name":"Děčín",
"country":"Czech Republic",
"districts":["Bynov","Boletice"]
}
REPLICATION
The database could be synchronized with external source, usually server, by setting replication. Client application just derive the Replication object with correct actions and set it to database as replication end point. Then whenever just call replicate(); We have prepared:
- Cloudant - 'lib/replicators/cloudant', see 'test/replication_cloudant_test.dart' for usage
Sample code with Cloudant, authentication is not necessary, when database is publicly accessible.
import "package:yomp_db/replicators/cloudant.dart" as ydb_rcl;
...
await db.open("yompdbsample", 1, {"cities":[]});
ydb_rcl.ReplicatorCloudant repi = new ydb_rcl.ReplicatorCloudant(/*url*/);
repi.setBasicAuthentication(/*username*/,/*password*/);
db.setReplication("cities",repi);
// now just replicate store cities
await db.replicate("cities"); // sends update to server and retrieves news
GIT
https://bitbucket.org/tomas-rokos/yomp
YOMP
Yomp is family of libraries created for data management for client and server development in Dart. The creation is based on pull model. The additions are done when needed, so there could be missing obvious methods, but they were just not needed so far.
Yomp is word for long-distance march carrying full kit.