Click here to Skip to main content
15,860,972 members
Articles / Database Development / NoSQL

RavenDB - An Introduction

,
Rate me:
Please Sign up or sign in to vote.
4.87/5 (38 votes)
28 Apr 2010CPOL7 min read 259.7K   2.7K   112  
An introduction to RavenDB - a new open source .NET document database using .NET 4.0 and VS 2010
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.PrettyPrinter;
using Microsoft.CSharp;
using Microsoft.CSharp.RuntimeBinder;
using Raven.Database.Linq.PrivateExtensions;

namespace Raven.Database.Linq
{
	public class QueryParsingUtils
	{
		public static string GenerateText(TypeDeclaration type)
		{
			var unit = new CompilationUnit();
			unit.AddChild(new Using(typeof (AbstractViewGenerator).Namespace));
			unit.AddChild(new Using(typeof (Enumerable).Namespace));
			unit.AddChild(new Using(typeof (int).Namespace));
			unit.AddChild(new Using(typeof (LinqOnDynamic).Namespace));
			unit.AddChild(type);

			var output = new CSharpOutputVisitor();
			unit.AcceptVisitor(output, null);

			return output.Text;
		}

		public static VariableDeclaration GetVariableDeclaration(string query)
		{
			var parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader("var q = " + query));

			var block = parser.ParseBlock();

			if (block.Children.Count != 1)
				throw new InvalidOperationException("Could not understand query: \r\n" + parser.Errors.ErrorOutput);

			var declaration = block.Children[0] as LocalVariableDeclaration;
			if (declaration == null)
				throw new InvalidOperationException("Only local variable decleration are allowed");

			if (declaration.Variables.Count != 1)
				throw new InvalidOperationException("Only one variable declaration is allowed");

			var variable = declaration.Variables[0];

			if (variable.Initializer == null)
				throw new InvalidOperationException("Variable declaration must have an initializer");

			var queryExpression = (variable.Initializer as QueryExpression);
			if (queryExpression == null)
				throw new InvalidOperationException("Variable initializer must be a query expression");

			var selectClause = queryExpression.SelectOrGroupClause as QueryExpressionSelectClause;
			if (selectClause == null)
				throw new InvalidOperationException("Variable initializer must be a select query expression");

			var createExpression = selectClause.Projection as ObjectCreateExpression;
			if (createExpression == null || createExpression.IsAnonymousType == false)
				throw new InvalidOperationException(
					"Variable initializer must be a select query expression returning an anonymous object");

			return variable;
		}

		public static Type Compile(string name, string queryText)
		{
			var provider = new CSharpCodeProvider(new Dictionary<string, string> {{"CompilerVersion", "v4.0"}});
			var results = provider.CompileAssemblyFromSource(new CompilerParameters
			{
				GenerateExecutable = false,
				GenerateInMemory = false,
				IncludeDebugInformation = true,
				ReferencedAssemblies =
					{
						typeof (AbstractViewGenerator).Assembly.Location,
						typeof (NameValueCollection).Assembly.Location,
						typeof (Enumerable).Assembly.Location,
						typeof (Binder).Assembly.Location,
					},
			}, queryText);

			if (results.Errors.HasErrors)
			{
				var sb = new StringBuilder()
					.AppendLine("Source code:")
					.AppendLine(queryText)
					.AppendLine();
				foreach (CompilerError error in results.Errors)
				{
					sb.AppendLine(error.ToString());
				}
				throw new InvalidOperationException(sb.ToString());
			}
			return results.CompiledAssembly.GetType(name);
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I've been a software developer since 1996 and have enjoyed C# since 2003. I have a Bachelor's degree in Computer Science and for some reason, a Master's degree in Business Administration. I currently do software development contracting/consulting.

Written By
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions