/// <summary> /// Initializes a new instance of the <see cref="CompositeQuery"/> class for a /// non-root composite query. /// </summary> /// <param name="parentCompositeQuery">The composite query that provides the data for the next level up in the composite resource.</param> /// <param name="displayName">The name to be used for the collection of data represented by the composite query.</param> /// <param name="orderedFieldNames">The names of the fields in selection order.</param> /// <param name="futureQuery">The results of the query, exposed by NHibernate as a collection of <see cref="Hashtable"/> instances.</param> /// <param name="isSingleItemResult">Indicates that the results should be treated as a single result in the output.</param> public CompositeQuery( CompositeQuery parentCompositeQuery, string displayName, string[] orderedFieldNames, IEnumerable <object> futureQuery, bool isSingleItemResult) { DisplayName = displayName; OrderedFieldNames = orderedFieldNames; IsSingleItemResult = isSingleItemResult; _parentCompositeQuery = parentCompositeQuery; _keyFields = new Lazy <string[]>(() => GetKeyFields(_futureQueryEnumerator.Value)); _dataFields = new Lazy <string[]>(() => GetDataFields(_futureQueryEnumerator.Value)); _dataByParentKey = new Lazy <IDictionary <string, List <Hashtable> > >(() => GetDataByParentKey(_futureQueryEnumerator.Value)); _futureQueryEnumerator = new Lazy <IEnumeratorWithCompletion>( () => { var enumerator = futureQuery.GetEnumerator(); if (enumerator.MoveNext()) { return(new EnumeratorWithCompletionWrapper(enumerator)); } return(null); }); ChildQueries = new List <CompositeQuery>(); }
private bool TryBuildCompositeQuery( XElement compositeDefinition, IResourceModel resourceModel, IDictionary <string, CompositeSpecificationParameter> filterCriteria, IDictionary <string, object> queryStringParameters, out CompositeQuery compositeQuery) { compositeQuery = null; var aliasGenerator = new AliasGenerator(CompositeDefinitionHelper.AliasPrefix); var builderContext = new HqlBuilderContext( new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder(), new Dictionary <string, object>(StringComparer.InvariantCultureIgnoreCase), null, 1, filterCriteria, queryStringParameters, new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase), aliasGenerator); compositeQuery = _compositeDefinitionProcessor.Process(compositeDefinition, resourceModel, builderContext); return(compositeQuery != null); }
public object Get( XElement compositeDefinition, IDictionary <string, CompositeSpecificationParameter> parameters, IDictionary <string, object> queryStringParameters, NullValueHandling nullValueHandling = NullValueHandling.Ignore) { var resourceModel = GetResourceModel(); bool closeSession = false; CompositeQuery query = null; object result = null; try { if (!CurrentSessionContext.HasBind(_sessionFactory)) { CurrentSessionContext.Bind(_sessionFactory.OpenSession()); closeSession = true; } var fieldSelections = GetFieldSelections(queryStringParameters); if (TryBuildCompositeQuery( compositeDefinition, resourceModel, parameters, queryStringParameters, out query)) { result = ProcessResults(query, fieldSelections, nullValueHandling); // Handle Single item requests if (query.IsSingleItemResult && result == null) { throw new NotFoundException("The specified resource could not be found."); } } else { // Return an appropriate response for an empty result if (IsSingleItemRequest(compositeDefinition, resourceModel, queryStringParameters)) { throw new NotFoundException("The specified resource could not be found."); } result = new List <IDictionary>(); } } catch (Exception e) { _logger.Error(e); throw; } finally { if (closeSession) { _sessionFactory.GetCurrentSession() .Close(); } } return(result); }
public IList <IDictionary> ProcessResults( CompositeQuery query, Hashtable parentRow, string[] parentKeys, IReadOnlyList <SelectedResourceMember> fieldSelections, NullValueHandling nullValueHandling) { var results = new List <IDictionary>(); var currentEnumerator = query.GetEnumerator(parentRow); do { // Nothing to enumerate? if (currentEnumerator == null || currentEnumerator.IsComplete) { return(results); } // Get current row var currentRow = (Hashtable)currentEnumerator.Current; if (currentRow == null) { break; } // If the child is outside the context of the parent, quit processing if (parentRow != null && !IsChildRow(parentKeys, parentRow, currentRow)) { break; } // Convert the row to serializable form var resultItem = GetItem(currentRow, query.DataFields, query.OrderedFieldNames, fieldSelections, nullValueHandling); // Process the children foreach (var childQuery in query.ChildQueries) { SelectedResourceMember selectedMember = null; string childCollectionName = childQuery.DisplayName; // Check to see if this collection should be included if (fieldSelections != null && fieldSelections.Count > 0) { selectedMember = fieldSelections.FirstOrDefault(x => x.Equals(childCollectionName) || x.Equals("*")); if (selectedMember == null) { continue; } } resultItem[childCollectionName] = ProcessResults( childQuery, currentRow, query.KeyFields, selectedMember == null ? null : selectedMember.Children, nullValueHandling) .ApplyCardinality(childQuery.IsSingleItemResult); } results.Add(resultItem); }while (currentEnumerator.MoveNext()); return(results); }
public object ProcessResults(CompositeQuery query, IReadOnlyList <SelectedResourceMember> fieldSelections, NullValueHandling nullValueHandling) { return(ProcessResults(query, null, null, fieldSelections, nullValueHandling) .ApplyCardinality(query.IsSingleItemResult)); }