OLD | NEW |
(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 /** |
| 8 * Represents a unique identifier for a [Model] stored in a datastore. |
| 9 * |
| 10 * The [Key] can be incomplete if it's id is `null`. In this case the id will |
| 11 * be automatically allocated and set at commit time. |
| 12 */ |
| 13 class Key { |
| 14 // Either KeyImpl or PartitionImpl |
| 15 final Object _parent; |
| 16 |
| 17 final Type type; |
| 18 final Object id; |
| 19 |
| 20 Key(Key parent, this.type, this.id) : _parent = parent { |
| 21 if (type == null) { |
| 22 throw new ArgumentError('The type argument must not be null.'); |
| 23 } |
| 24 if (id != null && id is! String && id is! int) { |
| 25 throw new ArgumentError( |
| 26 'The id argument must be an integer or a String.'); |
| 27 } |
| 28 } |
| 29 |
| 30 Key.emptyKey(Partition partition) |
| 31 : _parent = partition, type = null, id = null; |
| 32 |
| 33 /** |
| 34 * Parent of this [Key]. |
| 35 */ |
| 36 Key get parent { |
| 37 if (_parent is Key) { |
| 38 return _parent; |
| 39 } |
| 40 return null; |
| 41 } |
| 42 |
| 43 /** |
| 44 * The partition of this [Key]. |
| 45 */ |
| 46 Partition get partition { |
| 47 var obj = _parent; |
| 48 while (obj is! Partition) { |
| 49 obj = obj._parent; |
| 50 } |
| 51 return obj; |
| 52 } |
| 53 |
| 54 Key append(Type modelType, {Object id}) { |
| 55 return new Key(this, modelType, id); |
| 56 } |
| 57 |
| 58 bool get isEmpty => _parent is Partition; |
| 59 |
| 60 operator==(Object other) { |
| 61 return |
| 62 other is Key && |
| 63 _parent == other._parent && |
| 64 type == other.type && |
| 65 id == other.id; |
| 66 } |
| 67 |
| 68 int get hashCode => _parent.hashCode ^ type.hashCode ^ id.hashCode; |
| 69 } |
| 70 |
| 71 /** |
| 72 * Represents a datastore partition. |
| 73 * |
| 74 * A datastore is partitioned into namespaces. The default namespace is |
| 75 * `null`. |
| 76 */ |
| 77 class Partition { |
| 78 final String namespace; |
| 79 |
| 80 Partition(this.namespace) { |
| 81 if (namespace == '') { |
| 82 throw new ArgumentError( |
| 83 'The namespace must not be an empty string'); |
| 84 } |
| 85 } |
| 86 |
| 87 /** |
| 88 * Returns an empty [Key]. |
| 89 * |
| 90 * Entities where the parent [Key] is empty will create their own entity |
| 91 * group. |
| 92 */ |
| 93 Key get emptyKey => new Key.emptyKey(this); |
| 94 |
| 95 operator==(Object other) { |
| 96 return other is Partition && namespace == other.namespace; |
| 97 } |
| 98 |
| 99 int get hashCode => namespace.hashCode; |
| 100 } |
| 101 |
| 102 /** |
| 103 * Superclass for all model classes. |
| 104 * |
| 105 * Every model class has a [id] -- which must be an integer or a string, and |
| 106 * a [parentKey]. The [key] getter is returning the key for the model object. |
| 107 */ |
| 108 abstract class Model { |
| 109 Object id; |
| 110 Key parentKey; |
| 111 |
| 112 Key get key => parentKey.append(this.runtimeType, id: id); |
| 113 } |
| 114 |
| 115 /** |
| 116 * Superclass for all expanded model classes. |
| 117 * |
| 118 * The [ExpandoModel] class adds support for having dynamic properties. You can |
| 119 * set arbitrary fields on these models. The expanded values must be values |
| 120 * accepted by the [RawDatastore] implementation. |
| 121 */ |
| 122 @proxy |
| 123 abstract class ExpandoModel extends Model { |
| 124 final Map<String, Object> additionalProperties = {}; |
| 125 |
| 126 Object noSuchMethod(Invocation invocation) { |
| 127 var name = mirrors.MirrorSystem.getName(invocation.memberName); |
| 128 if (name.endsWith('=')) name = name.substring(0, name.length - 1); |
| 129 if (invocation.isGetter) { |
| 130 return additionalProperties[name]; |
| 131 } else if (invocation.isSetter) { |
| 132 var value = invocation.positionalArguments[0]; |
| 133 additionalProperties[name] = value; |
| 134 return value; |
| 135 } else { |
| 136 throw new ArgumentError('Unsupported noSuchMethod call on ExpandoModel'); |
| 137 } |
| 138 } |
| 139 } |
OLD | NEW |