| Index: pkg/gcloud/lib/src/db/models.dart
|
| diff --git a/pkg/gcloud/lib/src/db/models.dart b/pkg/gcloud/lib/src/db/models.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0419b286ba3f13aaf74272fdb72ab59363b9a549
|
| --- /dev/null
|
| +++ b/pkg/gcloud/lib/src/db/models.dart
|
| @@ -0,0 +1,139 @@
|
| +// 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;
|
| +
|
| +/**
|
| + * Represents a unique identifier for a [Model] stored in a datastore.
|
| + *
|
| + * The [Key] can be incomplete if it's id is `null`. In this case the id will
|
| + * be automatically allocated and set at commit time.
|
| + */
|
| +class Key {
|
| + // Either KeyImpl or PartitionImpl
|
| + final Object _parent;
|
| +
|
| + final Type type;
|
| + final Object id;
|
| +
|
| + Key(Key parent, this.type, this.id) : _parent = parent {
|
| + if (type == null) {
|
| + throw new ArgumentError('The type argument must not be null.');
|
| + }
|
| + if (id != null && id is! String && id is! int) {
|
| + throw new ArgumentError(
|
| + 'The id argument must be an integer or a String.');
|
| + }
|
| + }
|
| +
|
| + Key.emptyKey(Partition partition)
|
| + : _parent = partition, type = null, id = null;
|
| +
|
| + /**
|
| + * Parent of this [Key].
|
| + */
|
| + Key get parent {
|
| + if (_parent is Key) {
|
| + return _parent;
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + /**
|
| + * The partition of this [Key].
|
| + */
|
| + Partition get partition {
|
| + var obj = _parent;
|
| + while (obj is! Partition) {
|
| + obj = obj._parent;
|
| + }
|
| + return obj;
|
| + }
|
| +
|
| + Key append(Type modelType, {Object id}) {
|
| + return new Key(this, modelType, id);
|
| + }
|
| +
|
| + bool get isEmpty => _parent is Partition;
|
| +
|
| + operator==(Object other) {
|
| + return
|
| + other is Key &&
|
| + _parent == other._parent &&
|
| + type == other.type &&
|
| + id == other.id;
|
| + }
|
| +
|
| + int get hashCode => _parent.hashCode ^ type.hashCode ^ id.hashCode;
|
| +}
|
| +
|
| +/**
|
| + * Represents a datastore partition.
|
| + *
|
| + * A datastore is partitioned into namespaces. The default namespace is
|
| + * `null`.
|
| + */
|
| +class Partition {
|
| + final String namespace;
|
| +
|
| + Partition(this.namespace) {
|
| + if (namespace == '') {
|
| + throw new ArgumentError(
|
| + 'The namespace must not be an empty string');
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Returns an empty [Key].
|
| + *
|
| + * Entities where the parent [Key] is empty will create their own entity
|
| + * group.
|
| + */
|
| + Key get emptyKey => new Key.emptyKey(this);
|
| +
|
| + operator==(Object other) {
|
| + return other is Partition && namespace == other.namespace;
|
| + }
|
| +
|
| + int get hashCode => namespace.hashCode;
|
| +}
|
| +
|
| +/**
|
| + * Superclass for all model classes.
|
| + *
|
| + * Every model class has a [id] -- which must be an integer or a string, and
|
| + * a [parentKey]. The [key] getter is returning the key for the model object.
|
| + */
|
| +abstract class Model {
|
| + Object id;
|
| + Key parentKey;
|
| +
|
| + Key get key => parentKey.append(this.runtimeType, id: id);
|
| +}
|
| +
|
| +/**
|
| + * Superclass for all expanded model classes.
|
| + *
|
| + * The [ExpandoModel] class adds support for having dynamic properties. You can
|
| + * set arbitrary fields on these models. The expanded values must be values
|
| + * accepted by the [RawDatastore] implementation.
|
| + */
|
| +@proxy
|
| +abstract class ExpandoModel extends Model {
|
| + final Map<String, Object> additionalProperties = {};
|
| +
|
| + Object noSuchMethod(Invocation invocation) {
|
| + var name = mirrors.MirrorSystem.getName(invocation.memberName);
|
| + if (name.endsWith('=')) name = name.substring(0, name.length - 1);
|
| + if (invocation.isGetter) {
|
| + return additionalProperties[name];
|
| + } else if (invocation.isSetter) {
|
| + var value = invocation.positionalArguments[0];
|
| + additionalProperties[name] = value;
|
| + return value;
|
| + } else {
|
| + throw new ArgumentError('Unsupported noSuchMethod call on ExpandoModel');
|
| + }
|
| + }
|
| +}
|
|
|