Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Unified Diff: pkg/gcloud/lib/src/db/annotations.dart

Issue 804973002: Add appengine/gcloud/mustache dependencies. (Closed) Base URL: git@github.com:dart-lang/pub-dartlang-dart.git@master
Patch Set: Added AUTHORS/LICENSE/PATENTS files Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/gcloud/lib/src/datastore_impl.dart ('k') | pkg/gcloud/lib/src/db/db.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/gcloud/lib/src/db/annotations.dart
diff --git a/pkg/gcloud/lib/src/db/annotations.dart b/pkg/gcloud/lib/src/db/annotations.dart
new file mode 100644
index 0000000000000000000000000000000000000000..e158ad531947da7135c55a163d03e5824a2ce22f
--- /dev/null
+++ b/pkg/gcloud/lib/src/db/annotations.dart
@@ -0,0 +1,280 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of gcloud.db;
+
+/// Annotation used to mark dart classes which can be stored into datastore.
+///
+/// The `Kind` annotation on a class as well as other `Property` annotations on
+/// fields or getters of the class itself (and any of it's superclasses) up to
+/// the [Model] class describe the *mapping* of *dart objects* to datastore
+/// *entities*.
+///
+/// An "entity" is an object which can be stored into Google Cloud Datastore.
+/// It contains a number of named "properties", some of them might get indexed,
+/// others are not. A "property" value can be of a limited set of supported
+/// types (such as `int` and `String`).
+///
+/// Here is an example of a dart model class which can be stored into datastore:
+/// @Kind()
+/// class Person extends db.Model {
+/// @StringProperty()
+/// String name;
+///
+/// @IntProperty()
+/// int age;
+///
+/// @DateTimeProperty()
+/// DateTime dateOfBirth;
+/// }
+class Kind {
+ /// The kind name used when saving objects to datastore.
+ ///
+ /// If `null` the name will be the same as the class name at which the
+ /// annotation is placed.
+ final String name;
+
+ /// The type, either [ID_TYPE_INTEGER] or [ID_TYPE_STRING].
+ final IdType idType;
+
+ /// Annotation specifying the name of this kind and whether to use integer or
+ /// string `id`s.
+ ///
+ /// If `name` is omitted, it will default to the name of class to which this
+ /// annotation is attached to.
+ const Kind({this.name, this.idType: IdType.Integer});
+}
+
+/// The type used for id's of an entity.
+class IdType {
+ /// Use integer ids for identifying entities.
+ static const IdType Integer = const IdType(1);
+
+ /// Use string ids for identifying entities.
+ static const IdType String = const IdType(2);
+
+ final int _type;
+
+ const IdType(this._type);
+}
+
+/// Describes a property of an Entity.
+///
+/// Please see [Kind] for an example on how to use them.
+abstract class Property {
+ /// The name of the property.
+ ///
+ /// If it is `null`, the name will be the same as used in the
+ /// model class.
+ final String propertyName;
+
+ /// Specifies whether this property is required or not.
+ ///
+ /// If required is `true`, it will be enforced when saving model objects to
+ /// the datastore and when retrieving them.
+ final bool required;
+
+ /// Specifies whether this property should be indexed or not.
+ ///
+ /// When running queries no this property, it is necessary to set [indexed] to
+ /// `true`.
+ final bool indexed;
+
+ const Property({this.propertyName, this.required: false, this.indexed: true});
+
+ bool validate(ModelDB db, Object value) {
+ if (required && value == null) return false;
+ return true;
+ }
+
+ Object encodeValue(ModelDB db, Object value);
+
+ Object decodePrimitiveValue(ModelDB db, Object value);
+}
+
+/// An abstract base class for primitive properties which can e.g. be used
+/// within a composed `ListProperty`.
+abstract class PrimitiveProperty extends Property {
+ const PrimitiveProperty(
+ {String propertyName, bool required: false, bool indexed: true})
+ : super(propertyName: propertyName, required: required, indexed: indexed);
+
+ Object encodeValue(ModelDB db, Object value) => value;
+
+ Object decodePrimitiveValue(ModelDB db, Object value) => value;
+}
+
+/// A boolean [Property].
+///
+/// It will validate that values are booleans before writing them to the
+/// datastore and when reading them back.
+class BoolProperty extends PrimitiveProperty {
+ const BoolProperty(
+ {String propertyName, bool required: false, bool indexed: true})
+ : super(propertyName: propertyName, required: required, indexed: indexed);
+
+ bool validate(ModelDB db, Object value)
+ => super.validate(db, value) && (value == null || value is bool);
+}
+
+/// A integer [Property].
+///
+/// It will validate that values are integers before writing them to the
+/// datastore and when reading them back.
+class IntProperty extends PrimitiveProperty {
+ const IntProperty(
+ {String propertyName, bool required: false, bool indexed: true})
+ : super(propertyName: propertyName, required: required, indexed: indexed);
+
+ bool validate(ModelDB db, Object value)
+ => super.validate(db, value) && (value == null || value is int);
+}
+
+/// A double [Property].
+///
+/// It will validate that values are doubles before writing them to the
+/// datastore and when reading them back.
+class DoubleProperty extends PrimitiveProperty {
+ const DoubleProperty(
+ {String propertyName, bool required: false, bool indexed: true})
+ : super(propertyName: propertyName, required: required, indexed: indexed);
+
+ bool validate(ModelDB db, Object value)
+ => super.validate(db, value) && (value == null || value is double);
+}
+
+/// A string [Property].
+///
+/// It will validate that values are strings before writing them to the
+/// datastore and when reading them back.
+class StringProperty extends PrimitiveProperty {
+ const StringProperty(
+ {String propertyName, bool required: false, bool indexed: true})
+ : super(propertyName: propertyName, required: required, indexed: indexed);
+
+ bool validate(ModelDB db, Object value)
+ => super.validate(db, value) && (value == null || value is String);
+}
+
+/// A key [Property].
+///
+/// It will validate that values are keys before writing them to the
+/// datastore and when reading them back.
+class ModelKeyProperty extends PrimitiveProperty {
+ const ModelKeyProperty(
+ {String propertyName, bool required: false, bool indexed: true})
+ : super(propertyName: propertyName, required: required, indexed: indexed);
+
+ bool validate(ModelDB db, Object value)
+ => super.validate(db, value) && (value == null || value is Key);
+
+ Object encodeValue(ModelDB db, Object value) {
+ if (value == null) return null;
+ return db.toDatastoreKey(value);
+ }
+
+ Object decodePrimitiveValue(ModelDB db, Object value) {
+ if (value == null) return null;
+ return db.fromDatastoreKey(value as datastore.Key);
+ }
+}
+
+/// A binary blob [Property].
+///
+/// It will validate that values are blobs before writing them to the
+/// datastore and when reading them back. Blob values will be represented by
+/// List<int>.
+class BlobProperty extends PrimitiveProperty {
+ const BlobProperty({String propertyName, bool required: false})
+ : super(propertyName: propertyName, required: required, indexed: false);
+
+ // NOTE: We don't validate that the entries of the list are really integers
+ // of the range 0..255!
+ // If an untyped list was created the type check will always succeed. i.e.
+ // "[1, true, 'bar'] is List<int>" evaluates to `true`
+ bool validate(ModelDB db, Object value)
+ => super.validate(db, value) && (value == null || value is List<int>);
+
+ Object encodeValue(ModelDB db, Object value) {
+ if (value == null) return null;
+ return new datastore.BlobValue(value);
+ }
+
+ Object decodePrimitiveValue(ModelDB db, Object value) {
+ if (value == null) return null;
+
+ datastore.BlobValue blobValue = value;
+ return blobValue.bytes;
+ }
+}
+
+/// A datetime [Property].
+///
+/// It will validate that values are DateTime objects before writing them to the
+/// datastore and when reading them back.
+class DateTimeProperty extends PrimitiveProperty {
+ const DateTimeProperty(
+ {String propertyName, bool required: false, bool indexed: true})
+ : super(propertyName: propertyName, required: required, indexed: indexed);
+
+ bool validate(ModelDB db, Object value)
+ => super.validate(db, value) && (value == null || value is DateTime);
+
+ Object decodePrimitiveValue(ModelDB db, Object value) {
+ if (value is int) {
+ return
+ new DateTime.fromMillisecondsSinceEpoch(value ~/ 1000, isUtc: true);
+ }
+ return value;
+ }
+}
+
+
+/// A composed list [Property], with a `subProperty` for the list elements.
+///
+/// It will validate that values are List objects before writing them to the
+/// datastore and when reading them back. It will also validate the elements
+/// of the list itself.
+class ListProperty extends Property {
+ final PrimitiveProperty subProperty;
+
+ // TODO: We want to support optional list properties as well.
+ // Get rid of "required: true" here.
+ const ListProperty(this.subProperty,
+ {String propertyName, bool indexed: true})
+ : super(propertyName: propertyName, required: true, indexed: indexed);
+
+ bool validate(ModelDB db, Object value) {
+ if (!super.validate(db, value) || value is! List) return false;
+
+ for (var entry in value) {
+ if (!subProperty.validate(db, entry)) return false;
+ }
+ return true;
+ }
+
+ Object encodeValue(ModelDB db, Object value) {
+ if (value == null) return null;
+ List list = value;
+ if (list.length == 0) return null;
+ if (list.length == 1) return subProperty.encodeValue(db, list[0]);
+ return list.map(
+ (value) => subProperty.encodeValue(db, value)).toList();
+ }
+
+ Object decodePrimitiveValue(ModelDB db, Object value) {
+ if (value == null) return [];
+ if (value is! List) return [subProperty.decodePrimitiveValue(db, value)];
+ return (value as List)
+ .map((entry) => subProperty.decodePrimitiveValue(db, entry))
+ .toList();
+ }
+}
+
+/// A convenience [Property] for list of strings.
+class StringListProperty extends ListProperty {
+ const StringListProperty({String propertyName, bool indexed: true})
+ : super(const StringProperty(),
+ propertyName: propertyName, indexed: indexed);
+}
« no previous file with comments | « pkg/gcloud/lib/src/datastore_impl.dart ('k') | pkg/gcloud/lib/src/db/db.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698