entify 0.4.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 49

entify #

A library to ease the use of the datastore with the googleapis package.

Features #

Entity model mapping:

// ...

class Species {
  // This will handle the mapping between entify's Entity object and this model
  static final EntityBridge<Species> bridge = new EntityBridge<Species>();


  // You can use a factory constructor for setting up an object from an entity.
  // This isn't really needed, I just like to create these shorthand constructors,
  // the bridge.fromEntity can be called anywhere.
  factory Species.fromEntity(Entity e) => bridge.fromEntity(e, new Species());

  // Or you can use a vanilla constructor if you prefer.
  Species.entity(Entity e) {
    bridge.fromEntity(e, this);

  // Shorthand function for mapping this to an entify Entity object.
  Entity toEntity() => bridge.toEntity(this);

  String scientificName;
  String commonName;
  String status;

  // Fields can be renamed, marked as unindexed (not demonstrated here).
  @Persistent(name: "taxonomy")
  List<String> get taxonomyField => taxonomy.map((e) => e.toString()).toList();

  set taxonomyField(List<String> encodedTaxonomy) { /* ... */ }

  // This field is converted to/from a property via a getter/setter respectively.
  List<Taxon> taxonomy = [];

  // This is a lookup field generated from taxonomy, it doesn't need a setter.
  List<String> get taxonomyPaths { /* ... */ }

  // This is a non-persistent property.
  String get fullTaxonomyPath => taxonomy.join('/');

You can save some objects just by calling:

Future<Null> insertOrUpdateSpecies(DatastoreShell dsh, Iterable<Species> species) async {
  await (dsh.beginMutation()
      ..upsertAll(species.map((s) => s.toEntity())))

All the elements are optional, you can create googleapis level API objects and modify them if something is not supported.

Getting Started #

Check out the https://github.com/skawa-universe/endangered_species/ project for an example and details on the class provided above.

0.4.1 #

  • Added isEmpty/isNotEmpty properties to MutationBatch

0.4.0+2 #

  • Added an example, fixed linter warnings

0.4.0+1 #

  • Collection type adaptation fix

0.4.0 #

  • Dart 2 support

0.3.0 #

  • Entity kind is checked on deserialization (but can be disabled)
  • IndexedOverride is checked and stripped in Entity (though not for iterable value items, that is taken care of during API value object conversion)
  • Improved error handling
  • Introduced value deep copy to Entity.setPropertiesFrom, which will duplicate iterables (as lists), the default behavior is to shallow copy values
  • Added an Entity.copy constructor, which will by default create a deep copy of an entity, but this can be overridden
  • The EntityBridge uses metadata from both the getter and setter (previously only the getter was taken into account)

0.2.4 #

  • Added an option to the EntityBridge metadata classes skip setting properties that are missing in the entity.
  • Introduced version in Entity that saves the version in the fetch and query results.
  • EntityBridge can set version fields if they are available.
  • MutationBatch can return the affected keys with relatedKeys.
  • All get functions now handle deferred reads automatically.
  • Introduced the IndexOverride wrapper which can override whether an entity model field value has to be indexed or not.

0.2.3 #

  • Added containsProperty to Entity
  • The remove method on Entity returns the previously set value.
  • The read consistency can be specified with get calls
  • The default read consistency has been changed to null which means the service side default, which is different what it used to be with get calls and ancestor queries.

0.2.2 #

  • Entity: fixed propertyNames added toString
  • WrappedServerError will tell about the wrapped error in toString
  • Added a null check for the kind in the Key constructor
  • Incomplete Key values in entities are checked (they can still fail mutations if they are in a list)
  • Added EntityBridge methods that can be used as predicates: entityKindMatches and keyKindMatches

0.2.1+1 #

  • Fixed blob value handling

0.2.1 #

  • Added indexedIfNonNull.
  • Entity now supports accessing property names, so properties are now enumerable.
  • Empty commits are handled.
  • The setPropertiesFrom in the Entity class allows future proof entity updates.

0.2.0 #

  • Added support for transactions.
  • Renamed MutationBatch.execute and executeRaw to commit. The execute methods are deprecated now and will be removed in a future release.

0.1.2+2 #

  • Setters are optional for properties in entity model classes

0.1.2+1 #

  • Handles null values in fromValue better
  • Throws error if the entity model class does not have a key

0.1.2 #

  • Renamed fromProtocol to fromApiObject in Key and Entity to follow common naming convention
  • fromValue now handles empty values (treats them as null)
  • Entity throws more meaningful errors in fromApiObject

0.1.1+3 #

  • Added createKey method to EntityBridge
  • Created QueryResult interface

0.1.1 #

  • The bool parameter of toValue became a named parameter as it is recommended.


// Simple example using the DatastoreShell API only (no EntityBridge)
// This needs a Datastore emulator to be running (assuming the Google Cloud SDK is installed):
// gcloud beta emulators datastore start --project=example --no-store-on-disk
import "dart:async";
import "package:http/http.dart" as http;
import "package:googleapis/datastore/v1.dart" as ds;
import "package:entify/entify.dart";

const String appId = "example";

Future<ds.DatastoreApi> getDatastoreApi() async {
  // This example connects to the Datastore Emulator and can use a simple http client
  http.Client client = new http.Client();
  return new ds.DatastoreApi(client, rootUrl: "http://localhost:8081/");

Future<DatastoreShell> getDatastoreShell() =>
    getDatastoreApi().then((api) => new DatastoreShell(api, appId));

Future<void> insertOrUpdateEntity(DatastoreShell ds) async {
  Key entityKey = new Key("Event", name: "last");
  int now = new DateTime.now().millisecondsSinceEpoch;
  Entity e = new Entity();
  e.key = entityKey;
  e.indexed["timestamp"] = now;
  try {
    // Fetch the entity: getSingle throws EntityNotFoundError when the entity does not exist
    Entity old = await ds.getSingle(entityKey);
    Duration diff = new Duration(milliseconds: now - old["timestamp"]);
    print("Time difference between this run and last run: $diff");
    // It exists so we update the entity
    await ds.beginMutation().update(e).commit();
    print("Entity successfully updated");
  } on EntityNotFoundError {
    // If it does not exist we insert
    await ds.beginMutation().insert(e).commit();
    print("Entity successfully inserted");

Future<void> main() async {
  DatastoreShell ds = await getDatastoreShell();
  await insertOrUpdateEntity(ds);

Use this package as a library

1. Depend on it

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

  entify: ^0.4.1

2. Install it

You can install packages from the command line:

with pub:

$ pub get

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

3. Import it

Now in your Dart code, you can use:

import 'package:entify/entify.dart';
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 Apr 4, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6

Health suggestions

Fix lib/src/datastore/query.dart. (-16.51 points)

Analysis of lib/src/datastore/query.dart reported 36 hints, including:

line 12 col 12: Unnecessary new keyword.

line 26 col 25: Unnecessary new keyword.

line 29 col 13: Unnecessary new keyword.

line 35 col 30: Unnecessary new keyword.

line 36 col 26: Unnecessary new keyword.

Fix lib/src/datastore/shell.dart. (-14.39 points)

Analysis of lib/src/datastore/shell.dart reported 31 hints, including:

line 16 col 7: Unnecessary new keyword.

line 29 col 42: Unnecessary new keyword.

line 34 col 9: DO use curly braces for all flow control structures.

line 34 col 15: Unnecessary new keyword.

line 35 col 14: Unnecessary new keyword.

Fix lib/src/datastore/mutations.dart. (-12.22 points)

Analysis of lib/src/datastore/mutations.dart reported 26 hints, including:

line 28 col 19: Unnecessary new keyword.

line 38 col 19: Unnecessary new keyword.

line 49 col 19: Unnecessary new keyword.

line 58 col 19: Unnecessary new keyword.

line 69 col 29: Unnecessary new keyword.

Fix additional 8 files with analysis or formatting issues. (-36.04 points)

Additional issues in the following files:

  • lib/src/entity/model.dart (17 hints)
  • lib/src/datastore/entity.dart (14 hints)
  • lib/src/entity/builder.dart (12 hints)
  • lib/src/datastore/key.dart (11 hints)
  • lib/src/datastore/values.dart (8 hints)
  • lib/src/datastore/options.dart (5 hints)
  • lib/src/entity/metadata.dart (5 hints)
  • lib/src/entity/accessors.dart (2 hints)


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
googleapis >=0.39.0 <1.0.0 0.54.0
Transitive dependencies
_discoveryapis_commons 0.1.9
async 2.4.1
charcode 1.1.3
collection 1.14.12
http_parser 3.1.4
meta 1.1.8
path 1.6.4
pedantic 1.9.0
source_span 1.7.0
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
Dev dependencies
http any 0.12.0+4
test any