Browse Source

Implemented NullableTypeSerializer.

pull/28/head
rstam 15 years ago
parent
commit
750efc62d2
  1. 1
      Bson/Bson.csproj
  2. 7
      Bson/DefaultSerializer/BsonDefaultSerializationProvider.cs
  3. 74
      Bson/DefaultSerializer/Serializers/NullableTypeSerializer.cs
  4. 1
      BsonUnitTests/BsonUnitTests.csproj
  5. 164
      BsonUnitTests/DefaultSerializer/Serializers/NullableTypeSerializerTests.cs

1
Bson/Bson.csproj

@ -86,6 +86,7 @@
<Compile Include="DefaultSerializer\Conventions\ElementNameConventions.cs" /> <Compile Include="DefaultSerializer\Conventions\ElementNameConventions.cs" />
<Compile Include="DefaultSerializer\Conventions\IdMemberConventions.cs" /> <Compile Include="DefaultSerializer\Conventions\IdMemberConventions.cs" />
<Compile Include="DefaultSerializer\Conventions\IgnoreExtraElementsConventions.cs" /> <Compile Include="DefaultSerializer\Conventions\IgnoreExtraElementsConventions.cs" />
<Compile Include="DefaultSerializer\Serializers\NullableTypeSerializer.cs" />
<Compile Include="Exceptions\BsonInternalException.cs" /> <Compile Include="Exceptions\BsonInternalException.cs" />
<Compile Include="Exceptions\BsonSerializationException.cs" /> <Compile Include="Exceptions\BsonSerializationException.cs" />
<Compile Include="ObjectModel\IConvertibleToBsonDocument.cs" /> <Compile Include="ObjectModel\IConvertibleToBsonDocument.cs" />

7
Bson/DefaultSerializer/BsonDefaultSerializationProvider.cs

@ -88,6 +88,13 @@ namespace MongoDB.Bson.DefaultSerializer {
return GeneralEnumSerializer.GetSerializer(serializationOptions); return GeneralEnumSerializer.GetSerializer(serializationOptions);
} }
if (
type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>)
) {
return NullableTypeSerializer.Singleton;
}
if ( if (
type.IsClass && type.IsClass &&
!typeof(Array).IsAssignableFrom(type) && !typeof(Array).IsAssignableFrom(type) &&

74
Bson/DefaultSerializer/Serializers/NullableTypeSerializer.cs

@ -0,0 +1,74 @@
/* Copyright 2010 10gen 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
namespace MongoDB.Bson.DefaultSerializer {
public class NullableTypeSerializer : BsonBaseSerializer {
#region private static fields
private static NullableTypeSerializer singleton = new NullableTypeSerializer();
#endregion
#region constructors
private NullableTypeSerializer() {
}
#endregion
#region public static properties
public static NullableTypeSerializer Singleton {
get { return singleton; }
}
#endregion
#region public methods
public override object DeserializeElement(
BsonReader bsonReader,
Type nominalType,
out string name
) {
var bsonType = bsonReader.PeekBsonType();
if (bsonType == BsonType.Null) {
bsonReader.ReadNull(out name);
return null;
} else {
Type underlyingType = Nullable.GetUnderlyingType(nominalType);
return BsonSerializer.DeserializeElement(bsonReader, underlyingType, out name);
}
}
public override void SerializeElement(
BsonWriter bsonWriter,
Type nominalType,
string name,
object value
) {
if (value == null) {
bsonWriter.WriteNull(name);
} else {
Type underlyingType = Nullable.GetUnderlyingType(nominalType);
BsonSerializer.SerializeElement(bsonWriter, underlyingType, name, value);
}
}
#endregion
}
}

1
BsonUnitTests/BsonUnitTests.csproj

@ -81,6 +81,7 @@
<Compile Include="DefaultSerializer\Conventions\ElementNameConventionsTests.cs" /> <Compile Include="DefaultSerializer\Conventions\ElementNameConventionsTests.cs" />
<Compile Include="DefaultSerializer\SerializeFlagsTests.cs" /> <Compile Include="DefaultSerializer\SerializeFlagsTests.cs" />
<Compile Include="DefaultSerializer\Serializers\DateTimeSerializerTests.cs" /> <Compile Include="DefaultSerializer\Serializers\DateTimeSerializerTests.cs" />
<Compile Include="DefaultSerializer\Serializers\NullableTypeSerializerTests.cs" />
<Compile Include="IO\BsonBufferValueStraddlesChunksTests.cs" /> <Compile Include="IO\BsonBufferValueStraddlesChunksTests.cs" />
<Compile Include="Jira\CSharp70Tests.cs" /> <Compile Include="Jira\CSharp70Tests.cs" />
<Compile Include="Jira\CSharp71Tests.cs" /> <Compile Include="Jira\CSharp71Tests.cs" />

164
BsonUnitTests/DefaultSerializer/Serializers/NullableTypeSerializerTests.cs

@ -0,0 +1,164 @@
/* Copyright 2010 10gen 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 System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;
using MongoDB.Bson;
using MongoDB.Bson.DefaultSerializer;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
namespace MongoDB.BsonUnitTests.DefaultSerializer {
[TestFixture]
public class NullableTypeSerializerTests {
private class C {
public bool? Boolean { get; set; }
public DateTime? DateTime { get; set; }
[BsonDateTimeOptions(DateOnly = true)]
public DateTime? DateOnly { get; set; }
public double? Double { get; set; }
public Guid? Guid { get; set; }
public int? Int32 { get; set; }
public long? Int64 { get; set; }
public ObjectId? ObjectId { get; set; }
}
private const string template =
"{ " +
"'Boolean' : null, " +
"'DateTime' : null, " +
"'DateOnly' : null, " +
"'Double' : null, " +
"'Guid' : null, " +
"'Int32' : null, " +
"'Int64' : null, " +
"'ObjectId' : null" +
" }";
[Test]
public void TestAllNulls() {
C c = new C();
var json = c.ToJson();
var expected = template.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestBoolean() {
C c = new C { Boolean = true };
var json = c.ToJson();
var expected = template.Replace("'Boolean' : null", "'Boolean' : true").Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestDateTime() {
C c = new C { DateTime = BsonConstants.UnixEpoch };
var json = c.ToJson();
var expected = template.Replace("'DateTime' : null", "'DateTime' : { '$date' : 0 }").Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestDateOnly() {
C c = new C { DateOnly = BsonConstants.UnixEpoch };
var json = c.ToJson();
var expected = template.Replace("'DateOnly' : null", "'DateOnly' : { '$date' : 0 }").Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestDouble() {
C c = new C { Double = 1.5 };
var json = c.ToJson();
var expected = template.Replace("'Double' : null", "'Double' : 1.5").Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestGuid() {
C c = new C { Guid = Guid.Empty };
var json = c.ToJson();
var expected = template.Replace("'Guid' : null", "'Guid' : { '$binary' : 'AAAAAAAAAAAAAAAAAAAAAA==', '$type' : '03' }").Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestInt32() {
C c = new C { Int32 = 1 };
var json = c.ToJson();
var expected = template.Replace("'Int32' : null", "'Int32' : 1").Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestInt64() {
C c = new C { Int64 = 2 };
var json = c.ToJson();
var expected = template.Replace("'Int64' : null", "'Int64' : 2").Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestObjectId() {
C c = new C { ObjectId = ObjectId.Empty };
var json = c.ToJson();
var expected = template.Replace("'ObjectId' : null", "'ObjectId' : { '$oid' : '000000000000000000000000' }").Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = c.ToBson();
var rehydrated = BsonSerializer.DeserializeDocument<C>(bson);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
}
}
Loading…
Cancel
Save