ravendb /Raven.Database/Linq/AbstractTransformer.cs

Language C# Lines 162
MD5 Hash e23e2cd884feb474b5974e82f4f20eab
Repository https://github.com/nwendel/ravendb.git View Raw File
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Raven.Abstractions.Indexing;
using Raven.Abstractions.Linq;
using Raven.Database.Indexing;
using Raven.Json.Linq;

namespace Raven.Database.Linq
{
	public abstract class AbstractTransformer
	{
		private TransformerDefinition transformerDefinition;
		private byte[] cachedBytes;
		public IndexingFunc TransformResultsDefinition { get; set; }
		public string SourceCode { get; set; }

    public string Name { get { return transformerDefinition.Name; } }
		public string ViewText { get; set; }

		// ReSharper disable once InconsistentNaming
		protected DynamicNullObject __dynamic_null = new DynamicNullObject();


		public IEnumerable<dynamic> TransfromWith(IEnumerable<string> transformers, dynamic maybeItems)
		{
			return Enumerable.Aggregate(transformers, maybeItems, 
				(Func<dynamic, string, dynamic>)((items, transformer) => TransfromWith(transformer, items)));
		}

		public IEnumerable<dynamic> TransfromWith(string transformer, dynamic maybeItems)
		{
			if (CurrentTransformationScope.Current == null)
				throw new InvalidOperationException("TransfromWith was accessed without CurrentTransformationScope.Current being set");

			var storedTransformer = CurrentTransformationScope.Current.Database.IndexDefinitionStorage.GetTransformer(transformer);
			if (storedTransformer == null)
				throw new InvalidOperationException("No transformer with the name: " + transformer);

			var enumerable = maybeItems as IEnumerable;
			if ( enumerable != null && AnonymousObjectToLuceneDocumentConverter.ShouldTreatAsEnumerable(enumerable))
				return AllowAccessToResultsEvenIfTheyAreStupidInternalAnonymousTypes(storedTransformer.TransformResultsDefinition(enumerable.Cast<dynamic>()));

			return AllowAccessToResultsEvenIfTheyAreStupidInternalAnonymousTypes(storedTransformer.TransformResultsDefinition(new[] { maybeItems }));
		}

		// need to work around this: http://www.heartysoft.com/ashic/blog/2010/5/anonymous-types-c-sharp-4-dynamic
		private IEnumerable<object> AllowAccessToResultsEvenIfTheyAreStupidInternalAnonymousTypes(IEnumerable<object> items)
		{
			foreach (var item in items)
			{
				if (item == null)
					yield return new DynamicNullObject();
				if (item is ValueType ||
					item is string || 
					item is RavenJToken || 
					item is DynamicJsonObject || 
					item is DynamicNullObject ||
					item is IDictionary )
					yield return item;
				// assume that this is anonymous type, hence all internals, hence can't be access by the calling transformer
				var json = RavenJObject.FromObject(item);
				yield return new DynamicJsonObject(json);
			}
		}

		// Required for RavenDB-1519
		protected dynamic LoadDocument<TIgnored>(object key)
		{
			return LoadDocument(key);
		}

		protected dynamic LoadDocument(object key)
		{
			if (CurrentTransformationScope.Current == null)
				throw new InvalidOperationException("LoadDocument was called without CurrentTransformationScope.Current being set: " + key);

			return CurrentTransformationScope.Current.Retriever.Load(key);
		}

		[Obsolete("Use Parameter instead.")]
	    protected RavenJToken Query(string key)
	    {
			return Parameter(key);
		}

		[Obsolete("Use ParameterOrDefault instead.")]
		protected RavenJToken QueryOrDefault(string key, object val)
		{
			return ParameterOrDefault(key, val);
		}

	    protected RavenJToken Parameter(string key)
	    {
            if (CurrentTransformationScope.Current == null)
                throw new InvalidOperationException("Query was accessed without CurrentTransformationScope.Current being set");

	        RavenJToken value;
	        if(CurrentTransformationScope.Current.Retriever.TransformerParameters.TryGetValue(key, out value) == false)
                throw new InvalidOperationException("Query parameter "+key+ " was accessed, but it wasn't provided for this query.");
	        return value;

	    }

        protected RavenJToken ParameterOrDefault(string key, object val)
        {
            if (CurrentTransformationScope.Current == null)
                throw new InvalidOperationException("Query was accessed without CurrentTransformationScope.Current being set");

            RavenJToken value;
            if (CurrentTransformationScope.Current.Retriever.TransformerParameters.TryGetValue(key, out value) == false)
                return RavenJToken.FromObject(val);
            return value;

        }

	    public object Include(object key)
		{
			if (CurrentTransformationScope.Current == null)
				throw new InvalidOperationException("Include was called without CurrentTransformationScope.Current being set: " + key);

			return CurrentTransformationScope.Current.Retriever.Include(key);
	
		}

		protected IEnumerable<dynamic> Recurse(object item, Func<dynamic, dynamic> func)
		{
			return new RecursiveFunction(item, func).Execute();
		}

		public void Init(TransformerDefinition def)
		{
			transformerDefinition = def;
		}

		public byte[] GetHashCodeBytes()
		{
			if (cachedBytes != null)
				return cachedBytes;
			return cachedBytes = BitConverter.GetBytes(GetHashCode());
		}

		protected bool Equals(AbstractTransformer other)
		{
			return Equals(transformerDefinition, other.transformerDefinition);
		}

		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj)) return false;
			if (ReferenceEquals(this, obj)) return true;
			if (obj.GetType() != this.GetType()) return false;
			return Equals((AbstractTransformer)obj);
		}

		public override int GetHashCode()
		{
			return (transformerDefinition != null ? transformerDefinition.GetHashCode() : 0);
		}
	}
}
Back to Top