Esempio n. 1
0
        /// <summary>
        /// Checks if the entities are IReferenceByHiveId and of the same type if so returns true if the Ids match, otherwise false.
        /// </summary>
        /// <param name="op"></param>
        /// <param name="objectToCompare"></param>
        /// <returns></returns>
        internal static bool EntitiesAreEqual(this LinearHiveIndexOperation op, object objectToCompare)
        {
            if (ReferenceEquals(op.Entity, objectToCompare))
            {
                return(true);
            }

            var entityToCompare = objectToCompare as IReferenceByHiveId;

            if (entityToCompare == null)
            {
                return(false);
            }
            var entity = op.Entity as IReferenceByHiveId;

            if (entity == null)
            {
                return(false);
            }
            if (entity.GetType() != objectToCompare.GetType())
            {
                return(false);
            }
            if (entityToCompare.Id.IsNullValueOrEmpty() || entity.Id.IsNullValueOrEmpty())
            {
                return(false);
            }
            return(entity.Id.Value.Equals(entityToCompare.Id.Value));
        }
Esempio n. 2
0
        /// <summary>
        /// Removes the relation.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="transaction"></param>
        public void PerformRemoveRelation(IRelationById item, ExamineTransaction transaction)
        {
            Mandate.ParameterNotNull(item, "item");

            var delete = new LinearHiveIndexOperation()
            {
                OperationType = IndexOperationType.Delete,
                Id            = new Lazy <string>(item.GetCompositeId)
            };

            transaction.EnqueueIndexOperation(delete);
        }
        /// <summary>
        /// Detects if the Entity of the operation already exists in the queue list, if it does and it has been changed
        /// then this removes that operation from the queue list and returns true so that the newer version is added to the
        /// end of the list. If the item already exists in the queue but the entity has not been changed then it leaves the 
        /// original in the queue list. If the Entity doesn't exist in the queue then returns true so that it's added.
        /// </summary>
        /// <param name="indexOps"></param>
        /// <param name="op"></param>
        /// <returns>
        /// Returns true if the operation is a Delete operation.
        ///  then Returns false if the Entity is null.
        ///  then Returns false if the item was found in the queue list.
        ///  then Returns false if the item was not found in the queue list but has not been changed (not IsDirty())
        ///  then Returns true if the item was not found in the queue list and either has been changed or does not implement ICanBeDirty.
        /// </returns>
        internal static bool ShouldAddNewQueueItem(this List<LinearHiveIndexOperation> indexOps, LinearHiveIndexOperation op)
        {
            //always add delete ops
            if (op.OperationType == IndexOperationType.Delete) 
                return true;

            //if its not a Delete, the Entity should never be null
            if (op.Entity == null) 
                return false;

            //if (op.IsRevision())
            //{
            //    return true;   
            //}
                

            //checks if the operation exists by reference or by id
            var existingOperation = indexOps.Where(x => op.OperationType == IndexOperationType.Add
                                                        && (op.EntitiesAreEqual(x.Entity))).SingleOrDefault();
            
            //the item already exists
            if (existingOperation != null)
            {
                var dirtyEntity = op.Entity as ICanBeDirty;
                
                //if the item has been updated then remove the original entry from the queue list so the new version can be
                //re-added .
                if (dirtyEntity != null && dirtyEntity.IsDirty())
                {
                    indexOps.Remove(existingOperation);                    
                    return true;
                }
                //the item hasn't changed so leave the original
                return false;
            }

            return true;
        }
Esempio n. 4
0
        /// <summary>
        /// Detects if the Entity of the operation already exists in the queue list, if it does and it has been changed
        /// then this removes that operation from the queue list and returns true so that the newer version is added to the
        /// end of the list. If the item already exists in the queue but the entity has not been changed then it leaves the
        /// original in the queue list. If the Entity doesn't exist in the queue then returns true so that it's added.
        /// </summary>
        /// <param name="indexOps"></param>
        /// <param name="op"></param>
        /// <returns>
        /// Returns true if the operation is a Delete operation.
        ///  then Returns false if the Entity is null.
        ///  then Returns false if the item was found in the queue list.
        ///  then Returns false if the item was not found in the queue list but has not been changed (not IsDirty())
        ///  then Returns true if the item was not found in the queue list and either has been changed or does not implement ICanBeDirty.
        /// </returns>
        internal static bool ShouldAddNewQueueItem(this List <LinearHiveIndexOperation> indexOps, LinearHiveIndexOperation op)
        {
            //always add delete ops
            if (op.OperationType == IndexOperationType.Delete)
            {
                return(true);
            }

            //if its not a Delete, the Entity should never be null
            if (op.Entity == null)
            {
                return(false);
            }

            //if (op.IsRevision())
            //{
            //    return true;
            //}


            //checks if the operation exists by reference or by id
            var existingOperation = indexOps.Where(x => op.OperationType == IndexOperationType.Add &&
                                                   (op.EntitiesAreEqual(x.Entity))).SingleOrDefault();

            //the item already exists
            if (existingOperation != null)
            {
                var dirtyEntity = op.Entity as ICanBeDirty;

                //if the item has been updated then remove the original entry from the queue list so the new version can be
                //re-added .
                if (dirtyEntity != null && dirtyEntity.IsDirty())
                {
                    indexOps.Remove(existingOperation);
                    return(true);
                }
                //the item hasn't changed so leave the original
                return(false);
            }

            return(true);
        }
Esempio n. 5
0
 /// <summary>
 /// Checks if the operation is for a "Relation"
 /// </summary>
 /// <param name="op"></param>
 /// <returns></returns>
 internal static bool IsRelation(this LinearHiveIndexOperation op)
 {
     return(op.OperationType == IndexOperationType.Add &&
            op.ItemCategory == "Relation");
 }
Esempio n. 6
0
 /// <summary>
 /// Checks if the Entity assigned to the operation is a Revision{T}
 /// </summary>
 /// <param name="op"></param>
 /// <returns></returns>
 internal static bool IsRevision(this LinearHiveIndexOperation op)
 {
     return(op.OperationType == IndexOperationType.Add &&
            op.Entity != null &&
            op.Entity.GetType().IsOfGenericType(typeof(Revision <>)));
 }
Esempio n. 7
0
        /// <summary>
        /// Ensures all of the revision fields and data is stored in the index operation
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        internal void EnsureRevisionDataForIndexOperation <TEntity>(Revision <TEntity> s, LinearHiveIndexOperation t)
            where TEntity : class, IVersionableEntity
        {
            //now we need to update the ids, NOTE: the __NodeId is a composite id!
            t.Id = new Lazy <string>(() => s.Item.Id.Value.ToString() + "," + s.MetaData.Id.Value.ToString());
            t.AddOrUpdateField(FixedRevisionIndexFields.RevisionId, new Lazy <string>(() => s.MetaData.Id.Value.ToString()));

            //we also need to make sure the entity property is set to the Revision<TypedEntity> not just TypedEntity
            t.Entity = s;

            //ensure that the revision status type is stored in a document
            EnsureRevisionStatus(s.MetaData.StatusType);

            //add the revision status id
            t.AddOrUpdateField(FixedRevisionIndexFields.RevisionStatusId, s.MetaData.StatusType.Id.Value.ToString());
            t.AddOrUpdateField(FixedRevisionIndexFields.RevisionStatusAlias, s.MetaData.StatusType.Alias);
        }
Esempio n. 8
0
        /// <summary>
        /// Performs the delete.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="transaction"></param>
        /// <remarks>
        /// This will lookup all all related entities and remove them from the index
        /// </remarks>
        public void PerformDelete(string id, ExamineTransaction transaction)
        {
            Mandate.ParameterNotNullOrEmpty(id, "id");

            //NOTE: The below deletion process relies on having unique GUID ids across the board,
            // if you want to support int Ids, then we'll need to lookup the item type first
            // and delete different things based on that, i chose not to do that because
            // if for some reason the item with the Id that we're deleting isn't there then
            // any related instances will never be deleted whereas doing the below will delete all
            // related entities regardless.

            Action <IEnumerable <SearchResult> > addItemsToDeleteQueue = x =>
            {
                foreach (var r in x)
                {
                    var r1 = r;
                    transaction.EnqueueIndexOperation(new LinearHiveIndexOperation
                    {
                        OperationType = IndexOperationType.Delete,
                        Id            = new Lazy <string>(() => r1.Id)
                    });
                }
            };

            //First, check if there's relations for this id and remove any relations found
            var relations = ExamineManager.Search(
                ExamineManager.CreateSearchCriteria()
                .Should()
                .Id(id, FixedRelationIndexFields.SourceId)
                .Should()
                .Id(id, FixedRelationIndexFields.DestinationId).Compile());

            addItemsToDeleteQueue(relations);

            //next, check if there's any items (TypedEntity, AttributeDefinition, AttributeGroup) assigned to a schema by this id,
            // this will also delete all revisions of TypedEntity too
            var entities = ExamineManager.Search(
                ExamineManager.CreateSearchCriteria()
                .Should()
                .Id(id, FixedIndexedFields.SchemaId)
                .Should()
                .Id(id, FixedIndexedFields.EntityId)
                .Compile());

            addItemsToDeleteQueue(entities);

            //now, check if the item being deleted is an attribute type, if it is we need to remove all AttributeDefinitions associated
            // with it and then all TypedAttribute fields belonging to the TypedEntity that reference these AttributeDefinitions
            var attributeDefs = ExamineManager.Search(
                ExamineManager.CreateSearchCriteria()
                .Must()
                .Id(id, FixedIndexedFields.AttributeTypeId)
                .Must()
                .EntityType <AttributeDefinition>()
                .Compile());

            addItemsToDeleteQueue(attributeDefs);
            //now that we have the attribute defintions related to the typed attribute being deleted, we need to actually create new revisions
            // for any entity that had a schemas with these definitions on them.
            var schemaIds = attributeDefs.Select(x => x.Fields[FixedIndexedFields.SchemaId]).Distinct();

            foreach (var schemaId in schemaIds)
            {
                var criteria = ExamineManager.CreateSearchCriteria()
                               .Must().EntityType <TypedEntity>()
                               .Must().Id(schemaId, FixedIndexedFields.SchemaId)
                               //need to lookup latest because when we're supporting revisions, we will have more than one version of a TypedEntity
                               .Must().Range(FixedRevisionIndexFields.IsLatest, 1, 1);

                var latest = FilterLatestTypedEntities(
                    ExamineManager.Search(criteria.Compile()));

                //now that we have the latest TypedEntity for any Schema that had an AttributeDefinition on it that we are deleting
                // because we are deleting it's TypedAttribute, we need to make a new revision of
                //NOTE: If for some reason Revisions are disabled, this wont work
                foreach (var l in latest)
                {
                    //now that we have an entity, we'll loop through the attribute defs were removing an ensure it's fields are removed
                    foreach (var d in attributeDefs)
                    {
                        //remove all attributes starting with the prefix and attribute def alias
                        var d1 = d;
                        l.Fields.RemoveAll(x => x.Key.StartsWith(FixedAttributeIndexFields.AttributePrefix + d1.Fields[FixedIndexedFields.Alias]));
                        //conver the fields to be used in an index operation
                        var opFields = l.Fields.ToLazyDictionary(x => new ItemField(x));
                        //update some manual fields like the dates and revision ids
                        StoreDateTimeOffset(FixedIndexedFields.UtcModified, opFields, DateTimeOffset.UtcNow);
                        var revId = Guid.NewGuid().ToString("N");
                        opFields.AddOrUpdate(FixedRevisionIndexFields.RevisionId,
                                             new Lazy <ItemField>(() => new ItemField(revId)),
                                             (key, o) => new Lazy <ItemField>(() => new ItemField(revId)));

                        //need to generate a new id (which is composite)
                        var l1 = l;
                        var op = new LinearHiveIndexOperation
                        {
                            OperationType = IndexOperationType.Add,
                            Id            = new Lazy <string>(() => l1.Fields[FixedIndexedFields.EntityId] + "," + revId),
                            Fields        = opFields
                        };
                        //create the new revision without the fields
                        transaction.EnqueueIndexOperation(op);
                    }
                }
            }

            //finally, lookup the item itself and remove it
            var item = ExamineManager.Search(ExamineManager.CreateSearchCriteria().Must().Id(id).Compile());

            addItemsToDeleteQueue(item);
        }