Permalink
Browse files

Initial framework of LINQ implementation. Please note that this doesn…

…'t really do anything yet because the MongoLinqTranslator class is stubbed out.
  • Loading branch information...
1 parent 7e953d2 commit 4c1b6d2a80cf1b9b87157b9d758ebe63d864b9ef rstam committed Nov 18, 2011
@@ -1031,17 +1031,19 @@ MemberInfo memberInfo
private Func<object> GetCreator() {
if (creator == null) {
- Expression expression;
+ Expression body;
var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
var defaultConstructor = classType.GetConstructor(bindingFlags, null, new Type[0], null);
if (defaultConstructor != null) {
- expression = Expression.New(defaultConstructor);
+ // lambdaExpression = () => (object) new TClass()
+ body = Expression.New(defaultConstructor);
} else {
- var getUnitializedObjectInfo = typeof(FormatterServices).GetMethod("GetUninitializedObject", BindingFlags.Public | BindingFlags.Static);
- expression = Expression.Call(getUnitializedObjectInfo, Expression.Constant(classType));
+ // lambdaExpression = () => FormatterServices.GetUninitializedObject(classType)
+ var getUnitializedObjectMethodInfo = typeof(FormatterServices).GetMethod("GetUninitializedObject", BindingFlags.Public | BindingFlags.Static);
+ body = Expression.Call(getUnitializedObjectMethodInfo, Expression.Constant(classType));
}
- var lambda = Expression.Lambda<Func<object>>(expression);
- creator = lambda.Compile();
+ var lambdaExpression = Expression.Lambda<Func<object>>(body);
+ creator = lambdaExpression.Compile();
}
return creator;
}
@@ -1056,14 +1058,15 @@ MemberInfo memberInfo
shouldSerializeMethodInfo.IsPublic &&
shouldSerializeMethodInfo.ReturnType == typeof(bool)
) {
- // we need to construct a lambda wich does the following
- // (obj) => obj.ShouldSerializeXyz()
- var parameter = Expression.Parameter(typeof(object), "obj");
- var body = Expression.Call(
- Expression.Convert(parameter, classType),
- shouldSerializeMethodInfo
+ // lambdaExpression = (obj) => ((TClass) obj).ShouldSerializeXyz()
+ var objParameter = Expression.Parameter(typeof(object), "obj");
+ var lambdaExpression = Expression.Lambda<Func<object, bool>>(
+ Expression.Call(
+ Expression.Convert(objParameter, classType),
+ shouldSerializeMethodInfo
+ ),
+ objParameter
);
- var lambdaExpression = Expression.Lambda<Func<object, bool>>(body, parameter);
return lambdaExpression.Compile();
} else {
return null;
@@ -420,19 +420,20 @@ bool serializeDefaultValue
}
}
- var instance = Expression.Parameter(typeof(object), "obj");
- var lambda = Expression.Lambda<Func<object, object>>(
+ // lambdaExpression = (obj) => (object) ((TClass) obj).Member
+ var objParameter = Expression.Parameter(typeof(object), "obj");
+ var lambdaExpression = Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.MakeMemberAccess(
- Expression.Convert(instance, memberInfo.DeclaringType),
+ Expression.Convert(objParameter, memberInfo.DeclaringType),
memberInfo
),
typeof(object)
),
- instance
+ objParameter
);
- return lambda.Compile();
+ return lambdaExpression.Compile();
}
private Action<object, object> GetPropertySetter() {
@@ -443,19 +444,20 @@ bool serializeDefaultValue
throw new BsonSerializationException(message);
}
- var instance = Expression.Parameter(typeof(object), "obj");
- var argument = Expression.Parameter(typeof(object), "a");
- var lambda = Expression.Lambda<Action<object, object>>(
+ // lambdaExpression = (obj, value) => ((TClass) obj).SetMethod((TMember) value)
+ var objParameter = Expression.Parameter(typeof(object), "obj");
+ var valueParameter = Expression.Parameter(typeof(object), "value");
+ var lambdaExpression = Expression.Lambda<Action<object, object>>(
Expression.Call(
- Expression.Convert(instance, memberInfo.DeclaringType),
+ Expression.Convert(objParameter, memberInfo.DeclaringType),
setMethodInfo,
- Expression.Convert(argument, memberType)
+ Expression.Convert(valueParameter, memberType)
),
- instance,
- argument
+ objParameter,
+ valueParameter
);
- return lambda.Compile();
+ return lambdaExpression.Compile();
}
#endregion
}
@@ -179,6 +179,13 @@
<Compile Include="Internal\MongoReplyMessage.cs" />
<Compile Include="Internal\MongoUpdateMessage.cs" />
<Compile Include="Internal\ReplicaSetConnector.cs" />
+ <Compile Include="Linq\MongoLinqFindQuery.cs" />
+ <Compile Include="Linq\MongoLinqExtensionMethods.cs" />
+ <Compile Include="Linq\MongoQueryable.cs" />
+ <Compile Include="Linq\MongoQueryProvider.cs" />
+ <Compile Include="Linq\MongoLinqTranslator.cs" />
+ <Compile Include="Linq\MongoLinqQuery.cs" />
+ <Compile Include="Linq\TypeSystem.cs" />
<Compile Include="MongoUtils.cs" />
<Compile Include="MongoDefaults.cs" />
<Compile Include="GridFS\MongoGridFS.cs" />
@@ -0,0 +1,42 @@
+/* Copyright 2010-2011 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.Linq.Expressions;
+using System.Text;
+using System.Threading;
+
+namespace MongoDB.Driver.Linq {
+ /// <summary>
+ /// Static class that contains the Mongo Linq extension methods.
+ /// </summary>
+ public static class MongoLinqExtensionMethods {
+ /// <summary>
+ /// Returns an instance of IQueryable{{T}} for a MongoCollection.
+ /// </summary>
+ /// <typeparam name="T">The type of the returned documents.</typeparam>
+ /// <param name="collection">The name of the collection.</param>
+ /// <returns>An instance of IQueryable{{T}} for a MongoCollection.</returns>
+ public static IQueryable<T> AsQueryable<T>(
+ this MongoCollection collection
+ ) {
+ var provider = new MongoQueryProvider(collection);
+ return new MongoQueryable<T>(provider);
+ }
+ }
+}
@@ -0,0 +1,59 @@
+/* Copyright 2010-2011 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.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading;
+
+namespace MongoDB.Driver.Linq {
+ /// <summary>
+ /// Represents a LINQ query that has been translated to an equivalent MongoDB Find query.
+ /// </summary>
+ public class MongoLinqFindQuery : MongoLinqQuery {
+ #region private fields
+ private IMongoQuery query;
+ #endregion
+
+ #region constructor
+ /// <summary>
+ /// Initializes a new instance of the MongoLinqFindQuery class.
+ /// </summary>
+ /// <param name="collection">The collection being queried.</param>
+ /// <param name="query">The query.</param>
+ public MongoLinqFindQuery(
+ MongoCollection collection,
+ IMongoQuery query
+ )
+ : base(collection) {
+ this.query = query;
+ }
+ #endregion
+
+ #region public methods
+ /// <summary>
+ /// Executes the translated Find query.
+ /// </summary>
+ /// <returns>The result of executing the translated Find query.</returns>
+ public override IEnumerator<T> GetEnumerator<T>() {
+ var cursor = collection.FindAs<T>(query);
+ // TODO: modify the cursor with things like sort order, skip and limit
+ return cursor.GetEnumerator();
+ }
+ #endregion
+ }
+}
@@ -0,0 +1,66 @@
+/* Copyright 2010-2011 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.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading;
+
+namespace MongoDB.Driver.Linq {
+ /// <summary>
+ /// Represents a LINQ query that has been translated to a MongoDB query.
+ /// </summary>
+ public abstract class MongoLinqQuery {
+ #region protected fields
+ /// <summary>
+ /// The collection being queried.
+ /// </summary>
+ protected MongoCollection collection;
+ #endregion
+
+ #region constructors
+ /// <summary>
+ /// Initializes a new instance of the MongoLinqQuery class.
+ /// </summary>
+ /// <param name="collection">The collection being queried.</param>
+ protected MongoLinqQuery(
+ MongoCollection collection
+ ) {
+ this.collection = collection;
+ }
+ #endregion
+
+ #region public methods
+ /// <summary>
+ /// Executes a query that returns a single result (overridden by subclasses).
+ /// </summary>
+ /// <returns>The result of executing the query.</returns>
+ public virtual object Execute() {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Gets an enumerator for the results of a query that returns multiple results (overridden by subclasses).
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public virtual IEnumerator<T> GetEnumerator<T>() {
+ throw new NotSupportedException();
+ }
+ #endregion
+ }
+}
@@ -0,0 +1,45 @@
+/* Copyright 2010-2011 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.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading;
+
+namespace MongoDB.Driver.Linq {
+ /// <summary>
+ /// A translator from LINQ expression queries to Mongo queries.
+ /// </summary>
+ public static class MongoLinqTranslator {
+ #region public static methods
+ /// <summary>
+ /// A translator from LINQ queries to MongoDB queries.
+ /// </summary>
+ /// <param name="collection">The collection being queried.</param>
+ /// <param name="expression">The LINQ query.</param>
+ /// <returns>An instance of MongoLinqQuery.</returns>
+ public static MongoLinqQuery Translate(
+ MongoCollection collection,
+ Expression expression
+ ) {
+ // total hack just to test the initial LINQ framework
+ var query = MongoDB.Driver.Builders.Query.EQ("X", 1);
+ return new MongoLinqFindQuery(collection, query);
+ }
+ #endregion
+ }
+}
Oops, something went wrong.

0 comments on commit 4c1b6d2

Please sign in to comment.