| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- /* Copyright 2010-present MongoDB Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- using System;
- using System.Collections.Generic;
- using MongoDB.Bson;
- using MongoDB.Bson.IO;
- using MongoDB.Bson.Serialization;
- using MongoDB.Bson.Serialization.Attributes;
- using MongoDB.Bson.Serialization.Serializers;
- namespace MongoDB.Driver
- {
- /// <summary>
- /// Represents a DBRef (a convenient way to refer to a document).
- /// </summary>
- [BsonSerializer(typeof(MongoDBRefSerializer))]
- public class MongoDBRef : IEquatable<MongoDBRef>
- {
- // private fields
- private string _databaseName;
- private string _collectionName;
- private BsonValue _id;
- // constructors
- // default constructor is private and only used for deserialization
- private MongoDBRef()
- {
- }
- /// <summary>
- /// Creates a MongoDBRef.
- /// </summary>
- /// <param name="collectionName">The name of the collection that contains the document.</param>
- /// <param name="id">The Id of the document.</param>
- public MongoDBRef(string collectionName, BsonValue id)
- : this(null, collectionName, id)
- {
- }
- /// <summary>
- /// Creates a MongoDBRef.
- /// </summary>
- /// <param name="databaseName">The name of the database that contains the document.</param>
- /// <param name="collectionName">The name of the collection that contains the document.</param>
- /// <param name="id">The Id of the document.</param>
- public MongoDBRef(string databaseName, string collectionName, BsonValue id)
- {
- if (collectionName == null)
- {
- throw new ArgumentNullException("collectionName");
- }
- if (id == null)
- {
- throw new ArgumentNullException("id");
- }
- _databaseName = databaseName;
- _collectionName = collectionName;
- _id = id;
- }
- // public properties
- /// <summary>
- /// Gets the name of the database that contains the document.
- /// </summary>
- public string DatabaseName
- {
- get { return _databaseName; }
- }
- /// <summary>
- /// Gets the name of the collection that contains the document.
- /// </summary>
- public string CollectionName
- {
- get { return _collectionName; }
- }
- /// <summary>
- /// Gets the Id of the document.
- /// </summary>
- public BsonValue Id
- {
- get { return _id; }
- }
- // public operators
- /// <summary>
- /// Determines whether two specified MongoDBRef objects have different values.
- /// </summary>
- /// <param name="lhs">The first value to compare, or null.</param>
- /// <param name="rhs">The second value to compare, or null.</param>
- /// <returns>True if the value of lhs is different from the value of rhs; otherwise, false.</returns>
- public static bool operator !=(MongoDBRef lhs, MongoDBRef rhs)
- {
- return !MongoDBRef.Equals(lhs, rhs);
- }
- /// <summary>
- /// Determines whether two specified MongoDBRef objects have the same value.
- /// </summary>
- /// <param name="lhs">The first value to compare, or null.</param>
- /// <param name="rhs">The second value to compare, or null.</param>
- /// <returns>True if the value of lhs is the same as the value of rhs; otherwise, false.</returns>
- public static bool operator ==(MongoDBRef lhs, MongoDBRef rhs)
- {
- return MongoDBRef.Equals(lhs, rhs);
- }
- // public static methods
- /// <summary>
- /// Determines whether two specified MongoDBRef objects have the same value.
- /// </summary>
- /// <param name="lhs">The first value to compare, or null.</param>
- /// <param name="rhs">The second value to compare, or null.</param>
- /// <returns>True if the value of lhs is the same as the value of rhs; otherwise, false.</returns>
- public static bool Equals(MongoDBRef lhs, MongoDBRef rhs)
- {
- if ((object)lhs == null) { return (object)rhs == null; }
- return lhs.Equals(rhs);
- }
- // public methods
- /// <summary>
- /// Determines whether this instance and another specified MongoDBRef object have the same value.
- /// </summary>
- /// <param name="rhs">The MongoDBRef object to compare to this instance.</param>
- /// <returns>True if the value of the rhs parameter is the same as this instance; otherwise, false.</returns>
- public bool Equals(MongoDBRef rhs)
- {
- if ((object)rhs == null || GetType() != rhs.GetType()) { return false; }
- if ((object)this == (object)rhs) { return true; }
- // note: _databaseName can be null
- return string.Equals(_databaseName, rhs._databaseName) && _collectionName.Equals(rhs._collectionName) && _id.Equals(rhs._id);
- }
- /// <summary>
- /// Determines whether this instance and a specified object, which must also be a MongoDBRef object, have the same value.
- /// </summary>
- /// <param name="obj">The MongoDBRef object to compare to this instance.</param>
- /// <returns>True if obj is a MongoDBRef object and its value is the same as this instance; otherwise, false.</returns>
- public override bool Equals(object obj)
- {
- return Equals(obj as MongoDBRef); // works even if obj is null or of a different type
- }
- /// <summary>
- /// Returns the hash code for this MongoDBRef object.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- // see Effective Java by Joshua Bloch
- int hash = 17;
- hash = 37 * hash + ((_databaseName == null) ? 0 : _databaseName.GetHashCode());
- hash = 37 * hash + _collectionName.GetHashCode();
- hash = 37 * hash + _id.GetHashCode();
- return hash;
- }
- /// <summary>
- /// Returns a string representation of the value.
- /// </summary>
- /// <returns>A string representation of the value.</returns>
- public override string ToString()
- {
- if (_databaseName == null)
- {
- return string.Format("new MongoDBRef(\"{0}\", {1})", _collectionName, _id);
- }
- else
- {
- return string.Format("new MongoDBRef(\"{0}\", \"{1}\", {2})", _databaseName, _collectionName, _id);
- }
- }
- }
- /// <summary>
- /// Represents a serializer for MongoDBRefs.
- /// </summary>
- public class MongoDBRefSerializer : ClassSerializerBase<MongoDBRef>, IBsonDocumentSerializer
- {
- // private constants
- private static class Flags
- {
- public const long CollectionName = 1;
- public const long Id = 2;
- public const long DatabaseName = 4;
- }
- // private fields
- private readonly SerializerHelper _helper;
- // constructors
- /// <summary>
- /// Initializes a new instance of the <see cref="MongoDBRefSerializer"/> class.
- /// </summary>
- public MongoDBRefSerializer()
- {
- _helper = new SerializerHelper
- (
- new SerializerHelper.Member("$ref", Flags.CollectionName),
- new SerializerHelper.Member("$id", Flags.Id),
- new SerializerHelper.Member("$db", Flags.DatabaseName, isOptional: true)
- );
- }
- // public methods
- /// <summary>
- /// Tries to get the serialization info for a member.
- /// </summary>
- /// <param name="memberName">Name of the member.</param>
- /// <param name="serializationInfo">The serialization information.</param>
- /// <returns>
- /// <c>true</c> if the serialization info exists; otherwise <c>false</c>.
- /// </returns>
- public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializationInfo serializationInfo)
- {
- string elementName;
- IBsonSerializer serializer;
- switch (memberName)
- {
- case "DatabaseName":
- elementName = "$db";
- serializer = new StringSerializer();
- break;
- case "CollectionName":
- elementName = "$ref";
- serializer = new StringSerializer();
- break;
- case "Id":
- elementName = "$id";
- serializer = BsonValueSerializer.Instance;
- break;
- default:
- serializationInfo = null;
- return false;
- }
- serializationInfo = new BsonSerializationInfo(elementName, serializer, serializer.ValueType);
- return true;
- }
- // protected methods
- /// <summary>
- /// Deserializes a value.
- /// </summary>
- /// <param name="context">The deserialization context.</param>
- /// <param name="args">The deserialization args.</param>
- /// <returns>The value.</returns>
- protected override MongoDBRef DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
- {
- var bsonReader = context.Reader;
- string databaseName = null;
- string collectionName = null;
- BsonValue id = null;
- _helper.DeserializeMembers(context, (elementName, flag) =>
- {
- switch (flag)
- {
- case Flags.CollectionName: collectionName = bsonReader.ReadString(); break;
- case Flags.Id: id = BsonValueSerializer.Instance.Deserialize(context); break;
- case Flags.DatabaseName: databaseName = bsonReader.ReadString(); break;
- }
- });
- return new MongoDBRef(databaseName, collectionName, id);
- }
- /// <summary>
- /// Serializes a value.
- /// </summary>
- /// <param name="context">The serialization context.</param>
- /// <param name="args">The serialization args.</param>
- /// <param name="value">The value.</param>
- protected override void SerializeValue(BsonSerializationContext context, BsonSerializationArgs args, MongoDBRef value)
- {
- var bsonWriter = context.Writer;
- bsonWriter.WriteStartDocument();
- bsonWriter.WriteString("$ref", value.CollectionName);
- bsonWriter.WriteName("$id");
- BsonValueSerializer.Instance.Serialize(context, value.Id);
- if (value.DatabaseName != null)
- {
- bsonWriter.WriteString("$db", value.DatabaseName);
- }
- bsonWriter.WriteEndDocument();
- }
- }
- }
|