/Raven.Database/Server/Controllers/QueriesController.cs
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
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Threading.Tasks;
- using System.Web.Http;
- using Raven.Abstractions.Data;
- using Raven.Abstractions.Util.Encryptors;
- using Raven.Database.Data;
- using Raven.Json.Linq;
-
- namespace Raven.Database.Server.Controllers
- {
- public class QueriesController : RavenDbApiController
- {
- [HttpGet]
- [Route("queries")]
- [Route("databases/{databaseName}/queries")]
- public Task<HttpResponseMessage> QueriesGet()
- {
- return GetQueriesResponse(true);
- }
-
- [HttpPost]
- [Route("queries")]
- [Route("databases/{databaseName}/queries")]
- public Task<HttpResponseMessage> QueriesPost()
- {
- return GetQueriesResponse(false);
- }
-
- private async Task<HttpResponseMessage> GetQueriesResponse(bool isGet)
- {
- RavenJArray itemsToLoad;
- if (isGet == false)
- {
- itemsToLoad = await ReadJsonArrayAsync();
- AddRequestTraceInfo(sb =>
- {
- foreach (var item in itemsToLoad)
- {
- sb.Append("\t").Append(item).AppendLine();
- }
- });
- }
- else
- {
- itemsToLoad = new RavenJArray(GetQueryStringValues("id").Cast<object>());
- }
-
- var result = new MultiLoadResult();
- var loadedIds = new HashSet<string>();
- var includedIds = new HashSet<string>();
- var includes = GetQueryStringValues("include") ?? new string[0];
- var transformer = GetQueryStringValue("transformer") ?? GetQueryStringValue("resultTransformer");
- var transformerParameters = this.ExtractTransformerParameters();
- var transactionInformation = GetRequestTransaction();
- var includedEtags = new List<byte>();
-
- if (string.IsNullOrEmpty(transformer) == false)
- {
- var transformerDef = Database.IndexDefinitionStorage.GetTransformer(transformer);
- if (transformerDef == null)
- return GetMessageWithObject(new {Error = "No such transformer: " + transformer}, HttpStatusCode.BadRequest);
- includedEtags.AddRange(transformerDef.GetHashCodeBytes());
-
- }
-
- Database.TransactionalStorage.Batch(actions =>
- {
- foreach (RavenJToken item in itemsToLoad)
- {
- var value = item.Value<string>();
- if (loadedIds.Add(value) == false)
- continue;
- var documentByKey = string.IsNullOrEmpty(transformer)
- ? Database.Documents.Get(value, transactionInformation)
- : Database.Documents.GetWithTransformer(value, transformer, transactionInformation, transformerParameters, out includedIds);
- if (documentByKey == null)
- {
- if(ClientIsV3OrHigher)
- result.Results.Add(null);
- continue;
- }
- result.Results.Add(documentByKey.ToJson());
-
- if (documentByKey.Etag != null)
- includedEtags.AddRange(documentByKey.Etag.ToByteArray());
-
- includedEtags.Add((documentByKey.NonAuthoritativeInformation ?? false) ? (byte)0 : (byte)1);
- }
-
- var addIncludesCommand = new AddIncludesCommand(Database, transactionInformation, (etag, includedDoc) =>
- {
- includedEtags.AddRange(etag.ToByteArray());
- result.Includes.Add(includedDoc);
- }, includes, loadedIds);
-
- foreach (var item in result.Results.Where(item => item != null))
- {
- addIncludesCommand.Execute(item);
- }
- });
-
-
- foreach (var includedId in includedIds)
- {
- var doc = Database.Documents.Get(includedId, transactionInformation);
- if (doc == null)
- {
- continue;
- }
- includedEtags.AddRange(doc.Etag.ToByteArray());
- result.Includes.Add(doc.ToJson());
- }
-
- var computeHash = Encryptor.Current.Hash.Compute16(includedEtags.ToArray());
- Etag computedEtag = Etag.Parse(computeHash);
-
- if (MatchEtag(computedEtag))
- {
- return GetEmptyMessage(HttpStatusCode.NotModified);
- }
-
- var msg = GetMessageWithObject(result);
- WriteETag(computedEtag, msg);
-
- AddRequestTraceInfo(sb => sb.Append("Results count: {0}, includes count: {1}", result.Results.Count, result.Includes.Count).AppendLine());
-
- return msg;
- }
-
- }
- }