PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Raven.Database/Server/Controllers/QueriesController.cs

https://github.com/nwendel/ravendb
C# | 134 lines | 115 code | 19 blank | 0 comment | 17 complexity | fa71ddf62a015a6b37abf6dc304441fa MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, CC-BY-SA-3.0
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Net;
  4. using System.Net.Http;
  5. using System.Threading.Tasks;
  6. using System.Web.Http;
  7. using Raven.Abstractions.Data;
  8. using Raven.Abstractions.Util.Encryptors;
  9. using Raven.Database.Data;
  10. using Raven.Json.Linq;
  11. namespace Raven.Database.Server.Controllers
  12. {
  13. public class QueriesController : RavenDbApiController
  14. {
  15. [HttpGet]
  16. [Route("queries")]
  17. [Route("databases/{databaseName}/queries")]
  18. public Task<HttpResponseMessage> QueriesGet()
  19. {
  20. return GetQueriesResponse(true);
  21. }
  22. [HttpPost]
  23. [Route("queries")]
  24. [Route("databases/{databaseName}/queries")]
  25. public Task<HttpResponseMessage> QueriesPost()
  26. {
  27. return GetQueriesResponse(false);
  28. }
  29. private async Task<HttpResponseMessage> GetQueriesResponse(bool isGet)
  30. {
  31. RavenJArray itemsToLoad;
  32. if (isGet == false)
  33. {
  34. itemsToLoad = await ReadJsonArrayAsync();
  35. AddRequestTraceInfo(sb =>
  36. {
  37. foreach (var item in itemsToLoad)
  38. {
  39. sb.Append("\t").Append(item).AppendLine();
  40. }
  41. });
  42. }
  43. else
  44. {
  45. itemsToLoad = new RavenJArray(GetQueryStringValues("id").Cast<object>());
  46. }
  47. var result = new MultiLoadResult();
  48. var loadedIds = new HashSet<string>();
  49. var includedIds = new HashSet<string>();
  50. var includes = GetQueryStringValues("include") ?? new string[0];
  51. var transformer = GetQueryStringValue("transformer") ?? GetQueryStringValue("resultTransformer");
  52. var transformerParameters = this.ExtractTransformerParameters();
  53. var transactionInformation = GetRequestTransaction();
  54. var includedEtags = new List<byte>();
  55. if (string.IsNullOrEmpty(transformer) == false)
  56. {
  57. var transformerDef = Database.IndexDefinitionStorage.GetTransformer(transformer);
  58. if (transformerDef == null)
  59. return GetMessageWithObject(new {Error = "No such transformer: " + transformer}, HttpStatusCode.BadRequest);
  60. includedEtags.AddRange(transformerDef.GetHashCodeBytes());
  61. }
  62. Database.TransactionalStorage.Batch(actions =>
  63. {
  64. foreach (RavenJToken item in itemsToLoad)
  65. {
  66. var value = item.Value<string>();
  67. if (loadedIds.Add(value) == false)
  68. continue;
  69. var documentByKey = string.IsNullOrEmpty(transformer)
  70. ? Database.Documents.Get(value, transactionInformation)
  71. : Database.Documents.GetWithTransformer(value, transformer, transactionInformation, transformerParameters, out includedIds);
  72. if (documentByKey == null)
  73. {
  74. if(ClientIsV3OrHigher)
  75. result.Results.Add(null);
  76. continue;
  77. }
  78. result.Results.Add(documentByKey.ToJson());
  79. if (documentByKey.Etag != null)
  80. includedEtags.AddRange(documentByKey.Etag.ToByteArray());
  81. includedEtags.Add((documentByKey.NonAuthoritativeInformation ?? false) ? (byte)0 : (byte)1);
  82. }
  83. var addIncludesCommand = new AddIncludesCommand(Database, transactionInformation, (etag, includedDoc) =>
  84. {
  85. includedEtags.AddRange(etag.ToByteArray());
  86. result.Includes.Add(includedDoc);
  87. }, includes, loadedIds);
  88. foreach (var item in result.Results.Where(item => item != null))
  89. {
  90. addIncludesCommand.Execute(item);
  91. }
  92. });
  93. foreach (var includedId in includedIds)
  94. {
  95. var doc = Database.Documents.Get(includedId, transactionInformation);
  96. if (doc == null)
  97. {
  98. continue;
  99. }
  100. includedEtags.AddRange(doc.Etag.ToByteArray());
  101. result.Includes.Add(doc.ToJson());
  102. }
  103. var computeHash = Encryptor.Current.Hash.Compute16(includedEtags.ToArray());
  104. Etag computedEtag = Etag.Parse(computeHash);
  105. if (MatchEtag(computedEtag))
  106. {
  107. return GetEmptyMessage(HttpStatusCode.NotModified);
  108. }
  109. var msg = GetMessageWithObject(result);
  110. WriteETag(computedEtag, msg);
  111. AddRequestTraceInfo(sb => sb.Append("Results count: {0}, includes count: {1}", result.Results.Count, result.Includes.Count).AppendLine());
  112. return msg;
  113. }
  114. }
  115. }