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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of gcloud.db;
6
7 /// Annotation used to mark dart classes which can be stored into datastore.
8 ///
9 /// The `Kind` annotation on a class as well as other `Property` annotations on
10 /// fields or getters of the class itself (and any of it's superclasses) up to
11 /// the [Model] class describe the *mapping* of *dart objects* to datastore
12 /// *entities*.
13 ///
14 /// An "entity" is an object which can be stored into Google Cloud Datastore.
15 /// It contains a number of named "properties", some of them might get indexed,
16 /// others are not. A "property" value can be of a limited set of supported
17 /// types (such as `int` and `String`).
18 ///
19 /// Here is an example of a dart model class which can be stored into datastore:
20 /// @Kind()
21 /// class Person extends db.Model {
22 /// @StringProperty()
23 /// String name;
24 ///
25 /// @IntProperty()
26 /// int age;
27 ///
28 /// @DateTimeProperty()
29 /// DateTime dateOfBirth;
30 /// }
31 class Kind {
32 /// The kind name used when saving objects to datastore.
33 ///
34 /// If `null` the name will be the same as the class name at which the
35 /// annotation is placed.
36 final String name;
37
38 /// The type, either [ID_TYPE_INTEGER] or [ID_TYPE_STRING].
39 final IdType idType;
40
41 /// Annotation specifying the name of this kind and whether to use integer or
42 /// string `id`s.
43 ///
44 /// If `name` is omitted, it will default to the name of class to which this
45 /// annotation is attached to.
46 const Kind({this.name, this.idType: IdType.Integer});
47 }
48
49 /// The type used for id's of an entity.
50 class IdType {
51 /// Use integer ids for identifying entities.
52 static const IdType Integer = const IdType(1);
53
54 /// Use string ids for identifying entities.
55 static const IdType String = const IdType(2);
56
57 final int _type;
58
59 const IdType(this._type);
60 }
61
62 /// Describes a property of an Entity.
63 ///
64 /// Please see [Kind] for an example on how to use them.
65 abstract class Property {
66 /// The name of the property.
67 ///
68 /// If it is `null`, the name will be the same as used in the
69 /// model class.
70 final String propertyName;
71
72 /// Specifies whether this property is required or not.
73 ///
74 /// If required is `true`, it will be enforced when saving model objects to
75 /// the datastore and when retrieving them.
76 final bool required;
77
78 /// Specifies whether this property should be indexed or not.
79 ///
80 /// When running queries no this property, it is necessary to set [indexed] to
81 /// `true`.
82 final bool indexed;
83
84 const Property({this.propertyName, this.required: false, this.indexed: true});
85
86 bool validate(ModelDB db, Object value) {
87 if (required && value == null) return false;
88 return true;
89 }
90
91 Object encodeValue(ModelDB db, Object value);
92
93 Object decodePrimitiveValue(ModelDB db, Object value);
94 }
95
96 /// An abstract base class for primitive properties which can e.g. be used
97 /// within a composed `ListProperty`.
98 abstract class PrimitiveProperty extends Property {
99 const PrimitiveProperty(
100 {String propertyName, bool required: false, bool indexed: true})
101 : super(propertyName: propertyName, required: required, indexed: indexed);
102
103 Object encodeValue(ModelDB db, Object value) => value;
104
105 Object decodePrimitiveValue(ModelDB db, Object value) => value;
106 }
107
108 /// A boolean [Property].
109 ///
110 /// It will validate that values are booleans before writing them to the
111 /// datastore and when reading them back.
112 class BoolProperty extends PrimitiveProperty {
113 const BoolProperty(
114 {String propertyName, bool required: false, bool indexed: true})
115 : super(propertyName: propertyName, required: required, indexed: indexed);
116
117 bool validate(ModelDB db, Object value)
118 => super.validate(db, value) && (value == null || value is bool);
119 }
120
121 /// A integer [Property].
122 ///
123 /// It will validate that values are integers before writing them to the
124 /// datastore and when reading them back.
125 class IntProperty extends PrimitiveProperty {
126 const IntProperty(
127 {String propertyName, bool required: false, bool indexed: true})
128 : super(propertyName: propertyName, required: required, indexed: indexed);
129
130 bool validate(ModelDB db, Object value)
131 => super.validate(db, value) && (value == null || value is int);
132 }
133
134 /// A double [Property].
135 ///
136 /// It will validate that values are doubles before writing them to the
137 /// datastore and when reading them back.
138 class DoubleProperty extends PrimitiveProperty {
139 const DoubleProperty(
140 {String propertyName, bool required: false, bool indexed: true})
141 : super(propertyName: propertyName, required: required, indexed: indexed);
142
143 bool validate(ModelDB db, Object value)
144 => super.validate(db, value) && (value == null || value is double);
145 }
146
147 /// A string [Property].
148 ///
149 /// It will validate that values are strings before writing them to the
150 /// datastore and when reading them back.
151 class StringProperty extends PrimitiveProperty {
152 const StringProperty(
153 {String propertyName, bool required: false, bool indexed: true})
154 : super(propertyName: propertyName, required: required, indexed: indexed);
155
156 bool validate(ModelDB db, Object value)
157 => super.validate(db, value) && (value == null || value is String);
158 }
159
160 /// A key [Property].
161 ///
162 /// It will validate that values are keys before writing them to the
163 /// datastore and when reading them back.
164 class ModelKeyProperty extends PrimitiveProperty {
165 const ModelKeyProperty(
166 {String propertyName, bool required: false, bool indexed: true})
167 : super(propertyName: propertyName, required: required, indexed: indexed);
168
169 bool validate(ModelDB db, Object value)
170 => super.validate(db, value) && (value == null || value is Key);
171
172 Object encodeValue(ModelDB db, Object value) {
173 if (value == null) return null;
174 return db.toDatastoreKey(value);
175 }
176
177 Object decodePrimitiveValue(ModelDB db, Object value) {
178 if (value == null) return null;
179 return db.fromDatastoreKey(value as datastore.Key);
180 }
181 }
182
183 /// A binary blob [Property].
184 ///
185 /// It will validate that values are blobs before writing them to the
186 /// datastore and when reading them back. Blob values will be represented by
187 /// List<int>.
188 class BlobProperty extends PrimitiveProperty {
189 const BlobProperty({String propertyName, bool required: false})
190 : super(propertyName: propertyName, required: required, indexed: false);
191
192 // NOTE: We don't validate that the entries of the list are really integers
193 // of the range 0..255!
194 // If an untyped list was created the type check will always succeed. i.e.
195 // "[1, true, 'bar'] is List<int>" evaluates to `true`
196 bool validate(ModelDB db, Object value)
197 => super.validate(db, value) && (value == null || value is List<int>);
198
199 Object encodeValue(ModelDB db, Object value) {
200 if (value == null) return null;
201 return new datastore.BlobValue(value);
202 }
203
204 Object decodePrimitiveValue(ModelDB db, Object value) {
205 if (value == null) return null;
206
207 datastore.BlobValue blobValue = value;
208 return blobValue.bytes;
209 }
210 }
211
212 /// A datetime [Property].
213 ///
214 /// It will validate that values are DateTime objects before writing them to the
215 /// datastore and when reading them back.
216 class DateTimeProperty extends PrimitiveProperty {
217 const DateTimeProperty(
218 {String propertyName, bool required: false, bool indexed: true})
219 : super(propertyName: propertyName, required: required, indexed: indexed);
220
221 bool validate(ModelDB db, Object value)
222 => super.validate(db, value) && (value == null || value is DateTime);
223
224 Object decodePrimitiveValue(ModelDB db, Object value) {
225 if (value is int) {
226 return
227 new DateTime.fromMillisecondsSinceEpoch(value ~/ 1000, isUtc: true);
228 }
229 return value;
230 }
231 }
232
233
234 /// A composed list [Property], with a `subProperty` for the list elements.
235 ///
236 /// It will validate that values are List objects before writing them to the
237 /// datastore and when reading them back. It will also validate the elements
238 /// of the list itself.
239 class ListProperty extends Property {
240 final PrimitiveProperty subProperty;
241
242 // TODO: We want to support optional list properties as well.
243 // Get rid of "required: true" here.
244 const ListProperty(this.subProperty,
245 {String propertyName, bool indexed: true})
246 : super(propertyName: propertyName, required: true, indexed: indexed);
247
248 bool validate(ModelDB db, Object value) {
249 if (!super.validate(db, value) || value is! List) return false;
250
251 for (var entry in value) {
252 if (!subProperty.validate(db, entry)) return false;
253 }
254 return true;
255 }
256
257 Object encodeValue(ModelDB db, Object value) {
258 if (value == null) return null;
259 List list = value;
260 if (list.length == 0) return null;
261 if (list.length == 1) return subProperty.encodeValue(db, list[0]);
262 return list.map(
263 (value) => subProperty.encodeValue(db, value)).toList();
264 }
265
266 Object decodePrimitiveValue(ModelDB db, Object value) {
267 if (value == null) return [];
268 if (value is! List) return [subProperty.decodePrimitiveValue(db, value)];
269 return (value as List)
270 .map((entry) => subProperty.decodePrimitiveValue(db, entry))
271 .toList();
272 }
273 }
274
275 /// A convenience [Property] for list of strings.
276 class StringListProperty extends ListProperty {
277 const StringListProperty({String propertyName, bool indexed: true})
278 : super(const StringProperty(),
279 propertyName: propertyName, indexed: indexed);
280 }
OLDNEW
« 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