private static void BuildParentQueryConstraint(CollectionMatchingResultWrapper matchingResultWrapper, AttributeHolder[] attributeHolders, EntityAssociationAttribute lookupAttribute, SearchRequestDto searchRequestDto) { var searchValues = new List <string>(); var enumerable = attributeHolders as AttributeHolder[] ?? attributeHolders.ToArray(); var hasMainEntity = enumerable.Any(); foreach (var entity in attributeHolders) { var key = matchingResultWrapper.FetchKey(entity); var searchValue = SearchUtils.GetSearchValue(lookupAttribute, entity); if (!String.IsNullOrWhiteSpace(searchValue) && lookupAttribute.To != null) { searchValues.Add(searchValue); key.AppendEntry(lookupAttribute.To, searchValue); } } if (searchValues.Any()) { searchRequestDto.AppendSearchEntry(lookupAttribute.To, searchValues); } else if (hasMainEntity && lookupAttribute.Primary) { //if nothing was provided, it should return nothing, instead of all the values --> //if the main entity had a null on a primary element of the composition, nothing should be seen searchRequestDto.AppendSearchEntry(lookupAttribute.To, new[] { "-1231231312" }); } }
private SearchRequestDto BuildSearchRequestDto(ApplicationCompositionCollectionSchema applicationCompositionSchema, IEnumerable <EntityAssociationAttribute> lookupattributes, CollectionMatchingResultWrapper matchingResultWrapper, AttributeHolder[] attributeHolders, EntityMetadata collectionEntityMetadata, PaginatedSearchRequestDto paginatedSearch) { var searchRequestDto = (paginatedSearch == null || paginatedSearch.PageSize <= 0) ? new SearchRequestDto() : new PaginatedSearchRequestDto(); searchRequestDto.BuildProjection(applicationCompositionSchema, ContextLookuper.LookupContext().PrintMode); foreach (var lookupAttribute in lookupattributes) { if (lookupAttribute.From != null) { matchingResultWrapper.AddKey(lookupAttribute.To); BuildParentQueryConstraint(matchingResultWrapper, attributeHolders, lookupAttribute, searchRequestDto); } else if (lookupAttribute.Literal != null) { //if the from is a literal, don´t bother with the entities values searchRequestDto.AppendSearchEntry(lookupAttribute.To, lookupAttribute.Literal); } else if (lookupAttribute.Query != null) { searchRequestDto.AppendWhereClause(lookupAttribute.GetQueryReplacingMarkers(collectionEntityMetadata.Name)); } } var orderByField = applicationCompositionSchema.CollectionProperties.OrderByField; if (orderByField != null) { searchRequestDto.SearchSort = orderByField; searchRequestDto.SearchAscending = !orderByField.EndsWith("desc"); } // no pagination intended: return simple search var paginatedDTO = searchRequestDto as PaginatedSearchRequestDto; if (paginatedDTO == null || paginatedSearch == null) { return(searchRequestDto); } // pagination: merging the search dto's paginatedDTO.PageNumber = paginatedSearch.PageNumber; paginatedDTO.PageSize = paginatedSearch.PageSize; paginatedDTO.TotalCount = paginatedSearch.TotalCount; return(searchRequestDto); }
private void MatchResults(EntityRepository.SearchEntityResult resultCollections, CollectionMatchingResultWrapper matchingResultWrapper, string targetCollectionAttribute) { foreach (var resultCollection in resultCollections.ResultList) { var resultkey = new CollectionMatchingResultKey(); foreach (var key in matchingResultWrapper.Keys) { object result; if (!resultCollection.TryGetValue(key, out result)) { throw new Exception("key {0} was not present on the dictionary".Fmt(key)); } if (result != null) { resultkey.AppendEntry(key, result.ToString()); } } IDictionary <string, object> attributes; if (targetCollectionAttribute == "worklog_" && resultCollection.ContainsKey("relatedrecordkey") && resultCollection["relatedrecordkey"] != null) { //let´s see if this was provenient from a related record, workaround for //HAP-968 // see also HapagBaseApplicationDataSet#AppendRelatedRecordWCToWorklog resultkey = new CollectionMatchingResultKey(); resultkey.AppendEntry("recordkey", resultCollection["relatedrecordkey"] as string); attributes = matchingResultWrapper.FetchEntity(resultkey); if (attributes == null) { throw new Exception("could not locate entry"); } } else { attributes = matchingResultWrapper.FetchEntity(resultkey); } if (!attributes.ContainsKey(targetCollectionAttribute)) { attributes.Add(targetCollectionAttribute, new List <IDictionary <string, object> >()); } var collection = (List <IDictionary <string, object> >)attributes[targetCollectionAttribute]; collection.Add(resultCollection); } }
private void FetchAsync(SlicedEntityMetadata entityMetadata, EntityAssociation collectionAssociation, IDictionary <string, ApplicationCompositionSchema> compositionSchemas, IEnumerable <AttributeHolder> entitiesList, ContextHolder ctx, Dictionary <string, EntityRepository.SearchEntityResult> results, PaginatedSearchRequestDto paginatedSearch) { Quartz.Util.LogicalThreadContext.SetData("context", ctx); var lookupAttributes = collectionAssociation.Attributes; var collectionEntityMetadata = MetadataProvider.Entity(collectionAssociation.To); var targetCollectionAttribute = EntityUtil.GetRelationshipName(collectionAssociation.Qualifier); var applicationCompositionSchema = compositionSchemas[collectionAssociation.Qualifier] as ApplicationCompositionCollectionSchema; if (applicationCompositionSchema == null) { throw ExceptionUtil.InvalidOperation("collection schema {0} not found", collectionAssociation.Qualifier); } var lookupattributes = lookupAttributes as EntityAssociationAttribute[] ?? lookupAttributes.ToArray(); var attributeHolders = entitiesList as AttributeHolder[] ?? entitiesList.ToArray(); var matchingResultWrapper = new CollectionMatchingResultWrapper(); var searchRequestDto = BuildSearchRequestDto(applicationCompositionSchema, lookupattributes, matchingResultWrapper, attributeHolders, collectionEntityMetadata, paginatedSearch); searchRequestDto.QueryAlias = collectionAssociation.To; var firstAttributeHolder = attributeHolders.First(); if (applicationCompositionSchema.PrefilterFunction != null) { var dataSet = DataSetProvider.GetInstance().LookupDataSet(entityMetadata.ApplicationName); //we will call the function passing the first entry, altough this method could have been invoked for a list of items (printing) //TODO: think about it var preFilterParam = new CompositionPreFilterFunctionParameters(entityMetadata.AppSchema, searchRequestDto, firstAttributeHolder, applicationCompositionSchema); searchRequestDto = PrefilterInvoker.ApplyPreFilterFunction(dataSet, preFilterParam, applicationCompositionSchema.PrefilterFunction); } EntityRepository.SearchEntityResult queryResult = null; if (paginatedSearch == null) { //if there´s no pagination needed we can just do one thread-query queryResult = EntityRepository.GetAsRawDictionary(collectionEntityMetadata, searchRequestDto); } else { var tasks = new Task[2]; tasks[0] = Task.Factory.NewThread(() => { queryResult = EntityRepository.GetAsRawDictionary(collectionEntityMetadata, searchRequestDto); }); // one thread to count results for paginations tasks[1] = Task.Factory.NewThread(() => { paginatedSearch.TotalCount = EntityRepository.Count(collectionEntityMetadata, searchRequestDto); }); Task.WaitAll(tasks); // add paginationData to result // creating a new pagination data in order to have everything calculated correctly queryResult.PaginationData = new PaginatedSearchRequestDto( paginatedSearch.TotalCount, paginatedSearch.PageNumber, paginatedSearch.PageSize, paginatedSearch.SearchValues, paginatedSearch.PaginationOptions ); } // one thread to fetch results results.Add(collectionAssociation.Qualifier, queryResult); if (attributeHolders.Length == 1) { //default scenario, we have just one entity here firstAttributeHolder.Attributes.Add(targetCollectionAttribute, queryResult.ResultList); return; } MatchResults(queryResult, matchingResultWrapper, targetCollectionAttribute); }