Ejemplo n.º 1
0
        public override IEnumerable <T> PerformExecuteMany <T>(QueryDescription query, ObjectBinder objectBinder)
        {
            var direction = query.From.HierarchyScope;

            var criteria = new ExamineQueryVisitor(Helper.ExamineManager).Visit(query.Criteria);

            // Include revision status in query
            var revisionCriteria = Helper.ExamineManager.CreateSearchCriteria();

            revisionCriteria.Must().Field(FixedRevisionIndexFields.RevisionStatusAlias, query.From.RevisionStatus);

            IQuery finalQuery = null;

            // Only include the revision status if it was included in the query
            if (query.From.RevisionStatus != FromClause.RevisionStatusNotSpecified)
            {
                finalQuery = (criteria.ToString() == "") ? revisionCriteria.Compile() : ((LuceneSearchCriteria)criteria).Join((LuceneSearchCriteria)revisionCriteria.Compile(), BooleanClause.Occur.MUST);;
            }
            else
            {
                finalQuery = criteria;
            }

            IEnumerable <SearchResult> results = Helper.ExamineManager.Search(finalQuery);

            // Now apply an in-memory filter to account for some of the shortcomings of Lucene (e.g. no MAX support)
            var detailedResults = results.Select(x => new
            {
                EntityId         = HiveId.Parse(x.Fields.GetValue(FixedIndexedFields.EntityId, HiveId.Empty.ToString())),
                RevisionId       = HiveId.Parse(x.Fields.GetValue(FixedRevisionIndexFields.RevisionId, HiveId.Empty.ToString())),
                UtcStatusChanged = ExamineHelper.FromExamineDateTime(x.Fields, FixedIndexedFields.UtcStatusChanged),
                Result           = x
            }).ToArray();

            IEnumerable <SearchResult> maxByDate = detailedResults.GroupBy(x => x.EntityId,
                                                                           (key, matches) => matches.OrderByDescending(x => x.UtcStatusChanged).FirstOrDefault())
                                                   .Select(x => x.Result)
                                                   .ToArray();

            switch (query.ResultFilter.ResultFilterType)
            {
            case ResultFilterType.Any:
                return(new[] { maxByDate.Count() != 0 }.Cast <T>());

            case ResultFilterType.Count:
                //this is weird but returns an integer
                return(new[] { maxByDate.Count() }.Cast <T>());

            case ResultFilterType.Take:
                maxByDate = maxByDate.Take(query.ResultFilter.SelectorArgument);
                break;
            }

            if (typeof(T).IsAssignableFrom(query.ResultFilter.ResultType))
            {
                return(maxByDate.Distinct().Select(node => FrameworkContext.TypeMappers.Map <T>(node)));
            }

            return(Enumerable.Empty <T>());
        }
Ejemplo n.º 2
0
        private dynamic GetRealValueFromField(IAttributeSerializationDefinition serializationDefinition, string savedVal)
        {
            switch (serializationDefinition.DataSerializationType)
            {
            case DataSerializationTypes.Guid:
            case DataSerializationTypes.String:
            case DataSerializationTypes.LongString:
            case DataSerializationTypes.Boolean:
                return(savedVal);

            case DataSerializationTypes.SmallInt:
            case DataSerializationTypes.LargeInt:
                int intOut;
                if (int.TryParse(savedVal, out intOut))
                {
                    return(intOut);
                }
                throw new InvalidCastException("Could not parse value " + savedVal + " into an int Type");

            case DataSerializationTypes.Decimal:
                decimal decOut;
                if (decimal.TryParse(savedVal, out decOut))
                {
                    return(decOut);
                }
                throw new InvalidCastException("Could not parse value " + savedVal + " into an decimal Type");

            case DataSerializationTypes.Date:
                var dateTime = ExamineHelper.FromExamineDateTime(savedVal);
                if (dateTime != null)
                {
                    return(dateTime);
                }
                throw new InvalidCastException("Could not parse value " + savedVal + " into an DateTimeOffset Type");

            case DataSerializationTypes.ByteArray:
                throw new NotImplementedException();

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        public override RevisionData GetValue(SearchResult source)
        {
            var id          = HiveId.Parse(source.Fields[FixedRevisionIndexFields.RevisionId]);
            var revStatusId = Guid.Parse(source.Fields[FixedRevisionIndexFields.RevisionStatusId]);

            var revStatus = _helper.GetRevisionStatusType(revStatusId);

            if (revStatus == null)
            {
                throw new NotSupportedException("Could not find a revision status with status id: " + revStatusId.ToString("N"));
            }

            //NOTE: all dates on a revision will be the same correct? since they only exist one time. SD.
            return(new RevisionData(id, revStatus)
            {
                UtcCreated = ExamineHelper.FromExamineDateTime(source.Fields, FixedIndexedFields.UtcModified).Value,
                UtcModified = ExamineHelper.FromExamineDateTime(source.Fields, FixedIndexedFields.UtcModified).Value,
                UtcStatusChanged = ExamineHelper.FromExamineDateTime(source.Fields, FixedIndexedFields.UtcModified).Value
            });
        }
Ejemplo n.º 4
0
        /// <summary>
        /// When the Entity is a Revision, this checks the previous revisions committed during this transaction to see if the status has actually changed,
        /// if it determines that no previous entry exists in memory for this transaction, it will look up the entity in the index to see if the
        /// status has changed. It then sets the status changed date accordingly on the TypedEntity and in the index fields.
        /// </summary>
        /// <param name="op"></param>
        /// <param name="revisionsCommitted"></param>
        /// <returns>Returns a Tuple of the updated TypedEntity and RevisionData</returns>
        private Tuple <TypedEntity, RevisionData> EnsureCorrectStatusChangedDate(LinearHiveIndexOperation op, IEnumerable <Tuple <TypedEntity, RevisionData> > revisionsCommitted)
        {
            dynamic      r  = op.Entity;
            TypedEntity  te = r.Item;
            RevisionData rd = r.MetaData;

            //find all previous TypedEntities in the committed list matching this one
            var previous = revisionsCommitted.Where(x => x.Item1.Id.Value.ToString() == te.Id.Value.ToString())
                           .OrderBy(x => x.Item1.UtcModified)
                           .LastOrDefault();
            SearchResult latestEntry = GetLatestEntry(r);

            if (previous == null && latestEntry != null && latestEntry.Fields.ContainsKey(FixedRevisionIndexFields.RevisionStatusId) && latestEntry.Fields[FixedRevisionIndexFields.RevisionStatusId] != rd.StatusType.Id.Value.ToString())
            {
                //if there's nothing in memory but there's a previously saved entry with a different status id, then update the date
                te.UtcStatusChanged = rd.UtcCreated;
                op.Fields[FixedIndexedFields.UtcStatusChanged] = new ItemField(te.UtcStatusChanged.UtcDateTime)
                {
                    DataType = FieldDataType.DateTime
                };
            }
            else if (previous != null && previous.Item2.StatusType.Id.Value.ToString() != rd.StatusType.Id.Value.ToString())
            {
                //its changed in memory so update the date
                te.UtcStatusChanged = rd.UtcCreated;
                op.Fields[FixedIndexedFields.UtcStatusChanged] = new ItemField(te.UtcStatusChanged.UtcDateTime)
                {
                    DataType = FieldDataType.DateTime
                };
            }
            else if (latestEntry != null)
            {
                //the status hasn't changed and the entity is not new, set to latest entries status changed
                te.UtcStatusChanged = ExamineHelper.FromExamineDateTime(latestEntry.Fields, FixedIndexedFields.UtcStatusChanged).Value;
                op.Fields[FixedIndexedFields.UtcStatusChanged] = new ItemField(te.UtcStatusChanged.UtcDateTime)
                {
                    DataType = FieldDataType.DateTime
                };
            }
            return(new Tuple <TypedEntity, RevisionData>(te, rd));
        }