PageRenderTime 101ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/Raven.Database/Linq/AbstractTransformer.cs

https://github.com/nwendel/ravendb
C# | 162 lines | 128 code | 30 blank | 4 comment | 32 complexity | e23e2cd884feb474b5974e82f4f20eab MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, CC-BY-SA-3.0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using Raven.Abstractions.Indexing;
  6. using Raven.Abstractions.Linq;
  7. using Raven.Database.Indexing;
  8. using Raven.Json.Linq;
  9. namespace Raven.Database.Linq
  10. {
  11. public abstract class AbstractTransformer
  12. {
  13. private TransformerDefinition transformerDefinition;
  14. private byte[] cachedBytes;
  15. public IndexingFunc TransformResultsDefinition { get; set; }
  16. public string SourceCode { get; set; }
  17. public string Name { get { return transformerDefinition.Name; } }
  18. public string ViewText { get; set; }
  19. // ReSharper disable once InconsistentNaming
  20. protected DynamicNullObject __dynamic_null = new DynamicNullObject();
  21. public IEnumerable<dynamic> TransfromWith(IEnumerable<string> transformers, dynamic maybeItems)
  22. {
  23. return Enumerable.Aggregate(transformers, maybeItems,
  24. (Func<dynamic, string, dynamic>)((items, transformer) => TransfromWith(transformer, items)));
  25. }
  26. public IEnumerable<dynamic> TransfromWith(string transformer, dynamic maybeItems)
  27. {
  28. if (CurrentTransformationScope.Current == null)
  29. throw new InvalidOperationException("TransfromWith was accessed without CurrentTransformationScope.Current being set");
  30. var storedTransformer = CurrentTransformationScope.Current.Database.IndexDefinitionStorage.GetTransformer(transformer);
  31. if (storedTransformer == null)
  32. throw new InvalidOperationException("No transformer with the name: " + transformer);
  33. var enumerable = maybeItems as IEnumerable;
  34. if ( enumerable != null && AnonymousObjectToLuceneDocumentConverter.ShouldTreatAsEnumerable(enumerable))
  35. return AllowAccessToResultsEvenIfTheyAreStupidInternalAnonymousTypes(storedTransformer.TransformResultsDefinition(enumerable.Cast<dynamic>()));
  36. return AllowAccessToResultsEvenIfTheyAreStupidInternalAnonymousTypes(storedTransformer.TransformResultsDefinition(new[] { maybeItems }));
  37. }
  38. // need to work around this: http://www.heartysoft.com/ashic/blog/2010/5/anonymous-types-c-sharp-4-dynamic
  39. private IEnumerable<object> AllowAccessToResultsEvenIfTheyAreStupidInternalAnonymousTypes(IEnumerable<object> items)
  40. {
  41. foreach (var item in items)
  42. {
  43. if (item == null)
  44. yield return new DynamicNullObject();
  45. if (item is ValueType ||
  46. item is string ||
  47. item is RavenJToken ||
  48. item is DynamicJsonObject ||
  49. item is DynamicNullObject ||
  50. item is IDictionary )
  51. yield return item;
  52. // assume that this is anonymous type, hence all internals, hence can't be access by the calling transformer
  53. var json = RavenJObject.FromObject(item);
  54. yield return new DynamicJsonObject(json);
  55. }
  56. }
  57. // Required for RavenDB-1519
  58. protected dynamic LoadDocument<TIgnored>(object key)
  59. {
  60. return LoadDocument(key);
  61. }
  62. protected dynamic LoadDocument(object key)
  63. {
  64. if (CurrentTransformationScope.Current == null)
  65. throw new InvalidOperationException("LoadDocument was called without CurrentTransformationScope.Current being set: " + key);
  66. return CurrentTransformationScope.Current.Retriever.Load(key);
  67. }
  68. [Obsolete("Use Parameter instead.")]
  69. protected RavenJToken Query(string key)
  70. {
  71. return Parameter(key);
  72. }
  73. [Obsolete("Use ParameterOrDefault instead.")]
  74. protected RavenJToken QueryOrDefault(string key, object val)
  75. {
  76. return ParameterOrDefault(key, val);
  77. }
  78. protected RavenJToken Parameter(string key)
  79. {
  80. if (CurrentTransformationScope.Current == null)
  81. throw new InvalidOperationException("Query was accessed without CurrentTransformationScope.Current being set");
  82. RavenJToken value;
  83. if(CurrentTransformationScope.Current.Retriever.TransformerParameters.TryGetValue(key, out value) == false)
  84. throw new InvalidOperationException("Query parameter "+key+ " was accessed, but it wasn't provided for this query.");
  85. return value;
  86. }
  87. protected RavenJToken ParameterOrDefault(string key, object val)
  88. {
  89. if (CurrentTransformationScope.Current == null)
  90. throw new InvalidOperationException("Query was accessed without CurrentTransformationScope.Current being set");
  91. RavenJToken value;
  92. if (CurrentTransformationScope.Current.Retriever.TransformerParameters.TryGetValue(key, out value) == false)
  93. return RavenJToken.FromObject(val);
  94. return value;
  95. }
  96. public object Include(object key)
  97. {
  98. if (CurrentTransformationScope.Current == null)
  99. throw new InvalidOperationException("Include was called without CurrentTransformationScope.Current being set: " + key);
  100. return CurrentTransformationScope.Current.Retriever.Include(key);
  101. }
  102. protected IEnumerable<dynamic> Recurse(object item, Func<dynamic, dynamic> func)
  103. {
  104. return new RecursiveFunction(item, func).Execute();
  105. }
  106. public void Init(TransformerDefinition def)
  107. {
  108. transformerDefinition = def;
  109. }
  110. public byte[] GetHashCodeBytes()
  111. {
  112. if (cachedBytes != null)
  113. return cachedBytes;
  114. return cachedBytes = BitConverter.GetBytes(GetHashCode());
  115. }
  116. protected bool Equals(AbstractTransformer other)
  117. {
  118. return Equals(transformerDefinition, other.transformerDefinition);
  119. }
  120. public override bool Equals(object obj)
  121. {
  122. if (ReferenceEquals(null, obj)) return false;
  123. if (ReferenceEquals(this, obj)) return true;
  124. if (obj.GetType() != this.GetType()) return false;
  125. return Equals((AbstractTransformer)obj);
  126. }
  127. public override int GetHashCode()
  128. {
  129. return (transformerDefinition != null ? transformerDefinition.GetHashCode() : 0);
  130. }
  131. }
  132. }