Skip to content

Commit

Permalink
fixed projection problems with inheritance
Browse files Browse the repository at this point in the history
  • Loading branch information
craiggwilson committed Aug 10, 2010
1 parent 98e7d4b commit af265ba
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 27 deletions.
62 changes: 57 additions & 5 deletions source/MongoDB/Cursor_1.cs
Expand Up @@ -5,6 +5,9 @@
using MongoDB.Protocol;
using MongoDB.Serialization;
using System.Linq;
using MongoDB.Util;
using MongoDB.Configuration.Mapping.Model;
using MongoDB.Configuration.Mapping;

namespace MongoDB
{
Expand All @@ -25,6 +28,7 @@ public class Cursor<T> : ICursor<T> where T : class
private int _skip;
private bool _keepCursor;
private readonly ISerializationFactory _serializationFactory;
private readonly IMappingStore _mappingStore;

/// <summary>
/// Initializes a new instance of the <see cref="Cursor&lt;T&gt;"/> class.
Expand All @@ -33,14 +37,15 @@ public class Cursor<T> : ICursor<T> where T : class
/// <param name="connection">The conn.</param>
/// <param name="databaseName">Name of the database.</param>
/// <param name="collectionName">Name of the collection.</param>
internal Cursor(ISerializationFactory serializationFactory, Connection connection, string databaseName, string collectionName)
internal Cursor(ISerializationFactory serializationFactory, IMappingStore mappingStore, Connection connection, string databaseName, string collectionName)
{
//Todo: add public constrcutor for users to call
IsModifiable = true;
_connection = connection;
_databaseName = databaseName;
FullCollectionName = databaseName + "." + collectionName;
_serializationFactory = serializationFactory;
_mappingStore = mappingStore;
}

/// <summary>
Expand All @@ -54,8 +59,8 @@ internal Cursor(ISerializationFactory serializationFactory, Connection connectio
/// <param name="limit">The limit.</param>
/// <param name="skip">The skip.</param>
/// <param name="fields">The fields.</param>
internal Cursor(ISerializationFactory serializationFactory, Connection connection, string databaseName, string collectionName, object spec, int limit, int skip, object fields)
: this(serializationFactory, connection, databaseName, collectionName)
internal Cursor(ISerializationFactory serializationFactory, IMappingStore mappingStore, Connection connection, string databaseName, string collectionName, object spec, int limit, int skip, object fields)
: this(serializationFactory, mappingStore, connection, databaseName, collectionName)
{
//Todo: add public constrcutor for users to call
if (spec == null)
Expand Down Expand Up @@ -333,7 +338,7 @@ private void KillCursor(long cursorId)
NumberToReturn = _limit,
NumberToSkip = _skip,
Options = _options,
ReturnFieldSelector = _fields
ReturnFieldSelector = ConvertFieldSelectorToDocument(_fields)
};
}
else
Expand Down Expand Up @@ -391,5 +396,52 @@ private void KillCursor(long cursorId)
document["$query"] = _spec;
return document;
}

private Document ConvertFieldSelectorToDocument(object document)
{
Document doc;
if (document == null)
doc = new Document();
else
doc = ConvertExampleToDocument(document) as Document;

if (doc == null)
throw new NotSupportedException("An entity type is not supported in field selection. Use either a document or an anonymous type.");

var classMap = _mappingStore.GetClassMap(typeof(T));
if (doc.Count > 0 && (classMap.IsPolymorphic || classMap.IsSubClass))
doc[classMap.DiscriminatorAlias] = true;

return doc.Count == 0 ? null : doc;
}

private object ConvertExampleToDocument(object document)
{
if (document == null)
return null;

Document doc = document as Document;
if (doc != null)
return doc;

doc = new Document();

if (!(document is T)) //some type that is being used as an example
{
foreach (var prop in document.GetType().GetProperties())
{
if (!prop.CanRead)
continue;

object value = prop.GetValue(document, null);
if (!TypeHelper.IsNativeToMongo(prop.PropertyType))
value = ConvertExampleToDocument(value);

doc[prop.Name] = value;
}
}

return doc;
}
}
}
}
22 changes: 1 addition & 21 deletions source/MongoDB/MongoCollection_1.cs
Expand Up @@ -159,7 +159,7 @@ public T FindOne(string javascriptWhere)
public ICursor<T> Find(object spec, int limit, int skip, object fields){
if (spec == null)
spec = new Document();
return new Cursor<T>(_configuration.SerializationFactory, _connection, DatabaseName, Name, spec, limit, skip, fields);
return new Cursor<T>(_configuration.SerializationFactory, _configuration.MappingStore, _connection, DatabaseName, Name, spec, limit, skip, fields);
}

/// <summary>
Expand Down Expand Up @@ -603,25 +603,5 @@ private object EnsureUpdateDocument(object document)

return document;
}

private Document ConvertObjectToDocument(object document)
{
Document doc = document as Document;
if (doc != null)
return doc;

if (document is T)
{
var classMap = _configuration.MappingStore.GetClassMap(typeof(T));
foreach (PersistentMemberMap memberMap in classMap)
{
doc[memberMap.MemberName] = memberMap.GetValue(document);
}
}
else //anonymous type...
{

}
}
}
}
2 changes: 1 addition & 1 deletion source/MongoDB/Protocol/QueryMessage.cs
Expand Up @@ -17,7 +17,7 @@ namespace MongoDB.Protocol
/// [ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details.
/// }
/// </remarks>
internal class QueryMessage<T> : RequestMessageBase
internal class QueryMessage : RequestMessageBase
{
/// <summary>
/// Initializes a new instance of the <see cref="QueryMessage"/> class.
Expand Down
19 changes: 19 additions & 0 deletions source/MongoDB/Util/TypeHelper.cs
Expand Up @@ -54,5 +54,24 @@ internal static Type GetNonNullableType(Type type)
{
return IsNullableType(type) ? type.GetGenericArguments()[0] : type;
}

internal static bool IsNativeToMongo(Type type)
{
var typeCode = Type.GetTypeCode(type);

if (typeCode != TypeCode.Object)
return true;

if (type == typeof(Guid))
return true;

if (type == typeof(Oid))
return true;

if (type == typeof(byte[]))
return true;

return false;
}
}
}

0 comments on commit af265ba

Please sign in to comment.