Esempio n. 1
0
 private static void CheckAddBinaryProperties(RequestInsertVertex myInsertDefinition, IVertexType vertexType)
 {
     foreach (var prop in myInsertDefinition.BinaryProperties)
     {
         var propertyDef = vertexType.GetBinaryPropertyDefinition(prop.Key);
         if (propertyDef == null)
         {
             throw new AttributeDoesNotExistException(prop.Key, myInsertDefinition.VertexTypeName);
         }
     }
 }
Esempio n. 2
0
        private Tuple<long?, String, VertexUpdateDefinition> CreateVertexUpdateDefinition(
                                                                IVertex myVertex,
                                                                IVertexType myVertexType,
                                                                RequestUpdate myUpdate,
                                                                IPropertyProvider myPropertyCopy,
                                                                Int64 myTransaction,
                                                                SecurityToken mySecurity)
        {

            #region get removes

            List<long> toBeDeletedSingle = null;
            List<long> toBeDeletedHyper = null;
            List<long> toBeDeletedStructured = null;
            List<String> toBeDeletedUnstructured = null;
            List<long> toBeDeletedBinaries = null;

            if (myUpdate.RemovedAttributes != null)
            {
                #region remove each defined attribute

                foreach (var name in myUpdate.RemovedAttributes)
                {
                    if (myVertexType.HasAttribute(name))
                    {
                        var attr = myVertexType.GetAttributeDefinition(name);

                        switch (attr.Kind)
                        {
                            case AttributeType.Property:

                                if ((attr as IPropertyDefinition).IsMandatory)
                                    throw new MandatoryConstraintViolationException(attr.Name);

                                toBeDeletedStructured = toBeDeletedStructured ?? new List<long>();
                                toBeDeletedStructured.Add(attr.ID);
                                break;

                            case AttributeType.BinaryProperty:
                                toBeDeletedBinaries = toBeDeletedBinaries ?? new List<long>();
                                toBeDeletedBinaries.Add(attr.ID);
                                break;

                            case AttributeType.IncomingEdge:
                                //TODO: a better exception here.
                                throw new Exception("The edges on an incoming edge attribute can not be removed.");

                            case AttributeType.OutgoingEdge:
                                switch ((attr as IOutgoingEdgeDefinition).Multiplicity)
                                {
                                    case EdgeMultiplicity.HyperEdge:
                                    case EdgeMultiplicity.MultiEdge:
                                        toBeDeletedHyper = toBeDeletedHyper ?? new List<long>();
                                        toBeDeletedHyper.Add(attr.ID);
                                        break;
                                    case EdgeMultiplicity.SingleEdge:
                                        toBeDeletedSingle = toBeDeletedSingle ?? new List<long>();
                                        toBeDeletedSingle.Add(attr.ID);
                                        break;
                                    default:
                                        //TODO a better exception here
                                        throw new Exception("The enumeration EdgeMultiplicity was changed, but not this switch statement.");
                                }
                                break;

                            default:
                                //TODO: a better exception here.
                                throw new Exception("The enumeration AttributeType was updated, but not this switch statement.");
                        }
                    }
                    else
                    {
                        toBeDeletedUnstructured = toBeDeletedUnstructured ?? new List<String>();
                        toBeDeletedUnstructured.Add(name);
                    }
                }

                #endregion
            }

            if (myUpdate.RemovedUnstructuredProperties != null)
            {
                #region remove each unstructured property

                foreach (var name in myUpdate.RemovedUnstructuredProperties)
                {
                    if ((myVertexType.HasAttribute(name)) && (myVertexType.GetAttributeDefinition(name).Kind == AttributeType.Property))
                    {
                        toBeDeletedUnstructured = toBeDeletedUnstructured ?? new List<String>();
                        toBeDeletedUnstructured.Add(name);
                    }
                }

                #endregion
            }

            #endregion

            #region get update definitions

            IDictionary<Int64, HyperEdgeUpdateDefinition> toBeUpdatedHyper = null;
            IDictionary<Int64, SingleEdgeUpdateDefinition> toBeUpdatedSingle = null;
            IDictionary<Int64, IComparable> toBeUpdatedStructured = null;
            IDictionary<String, Object> toBeUpdatedUnstructured = null;
            IDictionary<Int64, StreamAddDefinition> toBeUpdatedBinaries = null;
            long? revision = null;
            string edition = myUpdate.UpdatedEdition;
            string comment = myUpdate.UpdatedComment;

            #region property copy things

            if (myPropertyCopy.StructuredProperties != null)
            {
                toBeUpdatedStructured = new Dictionary<long, IComparable>();
                foreach (var prop in myPropertyCopy.StructuredProperties)
                {
                    var propDef = myVertexType.GetPropertyDefinition(prop.Key);
                    CheckPropertyType(myVertexType.Name, prop.Value, propDef);
                    toBeUpdatedStructured.Add(propDef.ID, prop.Value);
                }
            }

            toBeUpdatedUnstructured = myPropertyCopy.UnstructuredProperties;

            #endregion

            #region binary properties
            if (myUpdate.UpdatedBinaryProperties != null)
            {
                foreach (var prop in myUpdate.UpdatedBinaryProperties)
                {
                    var propDef = myVertexType.GetBinaryPropertyDefinition(prop.Key);

                    toBeUpdatedBinaries = toBeUpdatedBinaries ?? new Dictionary<long, StreamAddDefinition>();
                    toBeUpdatedBinaries.Add(propDef.ID, new StreamAddDefinition(propDef.ID, prop.Value));
                }
            }
            #endregion

            #region collections

            if (myUpdate.AddedElementsToCollectionProperties != null || myUpdate.RemovedElementsFromCollectionProperties != null)
            {
                if (myUpdate.AddedElementsToCollectionProperties != null && myUpdate.RemovedElementsFromCollectionProperties != null)
                {
                    var keys = myUpdate.AddedElementsToCollectionProperties.Keys.Intersect(myUpdate.RemovedElementsFromCollectionProperties.Keys);
                    if (keys.CountIsGreater(0))
                    {
                        //TOTO a better exception here
                        throw new Exception("You can not add and remove items simultaneously on a collection attribute.");
                    }

                    if (myUpdate.AddedElementsToCollectionProperties != null)
                    {
                        foreach (var added in myUpdate.AddedElementsToCollectionProperties)
                        {
                            var propDef = myVertexType.GetPropertyDefinition(added.Key);

                            var hasValue = (propDef == null)
                                ? myVertex.HasUnstructuredProperty(added.Key)
                                : myVertex.HasProperty(propDef.ID);

                            //if it is not ICollectionWrapper something wrong with deserialization
                            var extractedValue = (!hasValue)
                                ? null
                                : (propDef == null)
                                    ? myVertex.GetUnstructuredProperty<ICollectionWrapper>(added.Key)
                                    : (ICollectionWrapper)propDef.GetValue(myVertex);

                            PropertyMultiplicity mult;
                            if (propDef != null)
                            {
                                //check types only for structured properties
                                foreach (var element in added.Value)
                                {
                                    CheckPropertyType(myVertexType.Name, element, propDef);
                                }
                                mult = propDef.Multiplicity;
                            }
                            else
                                mult = (added.Value is SetCollectionWrapper)
                                    ? PropertyMultiplicity.Set
                                    : PropertyMultiplicity.List;


                            var newValue = CreateNewCollectionWrapper(
                                (hasValue)
                                    ? extractedValue.Union(added.Value)
                                    : added.Value,
                                 mult);

                            if (propDef == null)
                            {
                                toBeUpdatedUnstructured = toBeUpdatedUnstructured ?? new Dictionary<String, object>();
                                toBeUpdatedUnstructured.Add(added.Key, newValue);
                            }
                            else
                            {
                                toBeUpdatedStructured = toBeUpdatedStructured ?? new Dictionary<long, IComparable>();
                                toBeUpdatedStructured.Add(propDef.ID, newValue);
                            }

                        }
                    }
                    if (myUpdate.RemovedElementsFromCollectionProperties != null)
                    {
                        foreach (var remove in myUpdate.RemovedElementsFromCollectionProperties)
                        {
                            var propDef = myVertexType.GetPropertyDefinition(remove.Key);

                            var hasValue = (propDef == null)
                                ? myVertex.HasUnstructuredProperty(remove.Key)
                                : myVertex.HasProperty(propDef.ID);

                            //no value, nothing to remove
                            if (!hasValue)
                                continue;

                            //if it is not ICollectionWrapper something wrong with deserialization
                            var extractedValue = (propDef == null)
                                ? myVertex.GetUnstructuredProperty<ICollectionWrapper>(remove.Key)
                                : (ICollectionWrapper)propDef.GetValue(myVertex);

                            PropertyMultiplicity mult = (propDef != null)
                                ? propDef.Multiplicity
                                : (extractedValue is SetCollectionWrapper)
                                    ? PropertyMultiplicity.Set
                                    : PropertyMultiplicity.List;

                            var newValue = CreateNewCollectionWrapper(extractedValue.Except(remove.Value), mult);

                            toBeUpdatedStructured.Add(propDef.ID, newValue);

                            if (propDef == null)
                            {
                                toBeUpdatedUnstructured = toBeUpdatedUnstructured ?? new Dictionary<String, object>();
                                toBeUpdatedUnstructured.Add(remove.Key, newValue);
                            }
                            else
                            {
                                toBeUpdatedStructured = toBeUpdatedStructured ?? new Dictionary<long, IComparable>();
                                toBeUpdatedStructured.Add(propDef.ID, newValue);
                            }

                        }
                    }
                }
            }

            #endregion

            #region extract vertex properties
            #region will be ignored
            long vertexID = 0L;
            long creationDate = 0L;
            long modificationDate = 0L;
            #endregion

            ExtractVertexProperties(ref edition, ref revision, ref comment, ref vertexID, ref creationDate, ref modificationDate, toBeUpdatedStructured);
            #endregion

            #region edge magic

            if (myUpdate.AddedElementsToCollectionEdges != null ||
                myUpdate.RemovedElementsFromCollectionEdges != null ||
                myUpdate.UpdateOutgoingEdges != null ||
                myUpdate.UpdateOutgoingEdgesProperties != null)
            {
                VertexInformation source = new VertexInformation(myVertex.VertexTypeID, myVertex.VertexID);

                #region update outgoing edges

                if (myUpdate.UpdateOutgoingEdges != null)
                {
                    foreach (var edge in myUpdate.UpdateOutgoingEdges)
                    {
                        var edgeDef = myVertexType.GetOutgoingEdgeDefinition(edge.EdgeName);

                        switch (edgeDef.Multiplicity)
                        {
                            case EdgeMultiplicity.SingleEdge:
                                {
                                    #region SingleEdge
                                    var targets = GetResultingVertexIDs(myTransaction, mySecurity, edge, edgeDef.TargetVertexType);
                                    if (targets == null || !targets.CountIsGreater(0))
                                    {
                                        toBeDeletedSingle = toBeDeletedSingle ?? new List<long>();
                                        toBeDeletedSingle.Add(edgeDef.ID);
                                    }
                                    else if (targets.CountIsGreater(1))
                                    {
                                        throw new Exception("Single edge can not have more than one target.");
                                    }
                                    else
                                    {
                                        ConvertUnknownProperties(edge, edgeDef.EdgeType);
                                        var structured = CreateStructuredUpdate(edge.StructuredProperties, edgeDef.EdgeType);
                                        var unstructured = CreateUnstructuredUpdate(edge.UnstructuredProperties);

                                        toBeUpdatedSingle = toBeUpdatedSingle ?? new Dictionary<long, SingleEdgeUpdateDefinition>();

                                        toBeUpdatedSingle.Add(edgeDef.ID,
                                                                new SingleEdgeUpdateDefinition(source,
                                                                                                targets.First(),
                                                                                                edgeDef.EdgeType.ID,
                                                                                                edge.Comment,
                                                                                                structured,
                                                                                                unstructured));
                                    }
                                    #endregion
                                }
                                break;

                            case EdgeMultiplicity.MultiEdge:
                                {
                                    #region MultiEdge
                                    // Why deleting the edge instances ???
                                    // they will never be inserted inside the update !!!
                                    // After delete the update will be needless because the edges are deleted !!!

                                    //List<SingleEdgeDeleteDefinition> internSingleDelete = null;
                                    //if (myVertex.HasOutgoingEdge(edgeDef.ID))
                                    //{
                                    //    internSingleDelete = new List<SingleEdgeDeleteDefinition>();
                                    //    foreach (var edgeInstance in myVertex.GetOutgoingHyperEdge(edgeDef.ID).GetTargetVertices())
                                    //    {
                                    //        internSingleDelete.Add(
                                    //            new SingleEdgeDeleteDefinition(source,
                                    //                                            new VertexInformation(edgeInstance.VertexTypeID,
                                    //                                                                    edgeInstance.VertexID)));
                                    //    }
                                    //}

                                    List<SingleEdgeUpdateDefinition> internSingleUpdate = null;
                                    var targets = GetResultingVertexIDs(myTransaction, mySecurity, edge, edgeDef.TargetVertexType);

                                    if (targets != null)
                                    {
                                        foreach (var target in targets)
                                        {
                                            internSingleUpdate = internSingleUpdate ?? new List<SingleEdgeUpdateDefinition>();
                                            internSingleUpdate.Add(new SingleEdgeUpdateDefinition(source, target, edgeDef.InnerEdgeType.ID));
                                        }
                                    }
                                    if (edge.ContainedEdges != null)
                                    {
                                        foreach (var innerEdge in edge.ContainedEdges)
                                        {
                                            targets = GetResultingVertexIDs(myTransaction, mySecurity, innerEdge, edgeDef.TargetVertexType);
                                            if (targets != null && targets.CountIsGreater(0))
                                            {
                                                ConvertUnknownProperties(innerEdge, edgeDef.InnerEdgeType);
                                                var structured = CreateStructuredUpdate(innerEdge.StructuredProperties, edgeDef.InnerEdgeType);
                                                var unstructured = CreateUnstructuredUpdate(innerEdge.UnstructuredProperties);

                                                foreach (var target in targets)
                                                {
                                                    internSingleUpdate = internSingleUpdate ?? new List<SingleEdgeUpdateDefinition>();

                                                    internSingleUpdate.Add(
                                                        new SingleEdgeUpdateDefinition(source,
                                                                                        target,
                                                                                        edgeDef.InnerEdgeType.ID,
                                                                                        innerEdge.Comment,
                                                                                        structured,
                                                                                        unstructured));
                                                }
                                            }

                                        }
                                    }
                                    ConvertUnknownProperties(edge, edgeDef.EdgeType);
                                    var outerStructured = CreateStructuredUpdate(edge.StructuredProperties, edgeDef.EdgeType);
                                    var outerUnstructured = CreateUnstructuredUpdate(edge.UnstructuredProperties);

                                    toBeUpdatedHyper = toBeUpdatedHyper ?? new Dictionary<long, HyperEdgeUpdateDefinition>();

                                    toBeUpdatedHyper.Add(edgeDef.ID,
                                                            new HyperEdgeUpdateDefinition(edgeDef.EdgeType.ID,
                                                                                            edge.Comment,
                                                                                            outerStructured,
                                                                                            outerUnstructured,
                                                                                            null,//internSingleDelete,
                                                                                            internSingleUpdate));
                                    #endregion
                                }
                                break;

                            case EdgeMultiplicity.HyperEdge:
                                break;

                            default:
                                throw new Exception("The enumeration EdgeMultiplicity was changed, but not this switch statement.");
                        }
                    }
                }

                #endregion

                #region update outgoing edges properties

                if (myUpdate.UpdateOutgoingEdgesProperties != null)
                {
                    foreach (var edge in myUpdate.UpdateOutgoingEdgesProperties)
                    {
                        var edgeDef = myVertexType
                                        .GetOutgoingEdgeDefinitions(true)
                                        .Where(_ => _.ID.Equals(edge.EdgeTypeID) ||
                                                _.InnerEdgeType.ID.Equals(edge.EdgeTypeID)).FirstOrDefault();

                        switch (edgeDef.Multiplicity)
                        {
                            case EdgeMultiplicity.SingleEdge:
                                {
                                    #region SingleEdge
                                    //var targets = GetResultingVertexIDs(myTransaction, mySecurity, edge, edgeDef.TargetVertexType);

                                    //if (targets == null || !targets.CountIsGreater(0))
                                    //{
                                    //    toBeDeletedSingle = toBeDeletedSingle ?? new List<long>();
                                    //    toBeDeletedSingle.Add(edgeDef.ID);
                                    //}
                                    //else if (targets.CountIsGreater(1))
                                    //{
                                    //    throw new Exception("Single edge can not have more than one target.");
                                    //}
                                    //else
                                    //{
                                    //    ConvertUnknownProperties(edge, edgeDef.EdgeType);
                                    //    var structured = CreateStructuredUpdate(edge.StructuredProperties, edgeDef.EdgeType);
                                    //    var unstructured = CreateUnstructuredUpdate(edge.UnstructuredProperties);

                                    //    toBeUpdatedSingle = toBeUpdatedSingle ?? new Dictionary<long, SingleEdgeUpdateDefinition>();

                                    //    toBeUpdatedSingle.Add(edgeDef.ID,
                                    //                            new SingleEdgeUpdateDefinition(source,
                                    //                                                            targets.First(),
                                    //                                                            edgeDef.EdgeType.ID,
                                    //                                                            edge.Comment,
                                    //                                                            structured,
                                    //                                                            unstructured));
                                    //}
                                    #endregion
                                }
                                break;

                            case EdgeMultiplicity.MultiEdge:
                                {
                                    #region MultiEdge
                                    List<SingleEdgeUpdateDefinition> internSingleUpdate = null;

                                    var targets =
                                        myVertex
                                        .GetOutgoingEdge(edgeDef.ID)
                                        .GetTargetVertices()
                                        .Select(_ => new VertexInformation(_.VertexTypeID,
                                                                            _.VertexID));

                                    if (targets != null && targets.CountIsGreater(0))
                                    {
                                        var structured = edge.UpdatedStructuredProperties;
                                        var unstructured = edge.UpdatedUnstructuredProperties;

                                        foreach (var target in targets)
                                        {
                                            internSingleUpdate = internSingleUpdate ?? new List<SingleEdgeUpdateDefinition>();

                                            internSingleUpdate.Add(
                                                new SingleEdgeUpdateDefinition(source,
                                                                                target,
                                                                                edgeDef.InnerEdgeType.ID,
                                                                                edge.CommentUpdate,
                                                                                structured,
                                                                                unstructured));
                                        }
                                    }

                                    toBeUpdatedHyper = toBeUpdatedHyper ??
                                                        new Dictionary<long, HyperEdgeUpdateDefinition>();

                                    if (toBeUpdatedHyper.ContainsKey(edgeDef.ID))
                                    {
                                        var temp = toBeUpdatedHyper[edgeDef.ID];
                                        toBeUpdatedHyper.Remove(edgeDef.ID);
                                        toBeUpdatedHyper.Add(edgeDef.ID,
                                                            MergeToBeAddedHyperEdgeUpdates(temp,
                                                                                            internSingleUpdate));
                                    }
                                    else
                                        toBeUpdatedHyper.Add(edgeDef.ID,
                                                                new HyperEdgeUpdateDefinition(edgeDef.EdgeType.ID,
                                                                                                null,
                                                                                                null,
                                                                                                null,
                                                                                                null,
                                                                                                internSingleUpdate));

                                    #endregion
                                }
                                break;

                            case EdgeMultiplicity.HyperEdge:
                                break;

                            default:
                                throw new Exception("The enumeration EdgeMultiplicity was changed, but not this switch statement.");
                        }
                    }
                }

                #endregion

                #region update AddedElementsToCollectionEdges

                if (myUpdate.AddedElementsToCollectionEdges != null)
                {
                    foreach (var hyperEdge in myUpdate.AddedElementsToCollectionEdges)
                    {
                        var edgeDef = myVertexType.GetOutgoingEdgeDefinition(hyperEdge.Key);

                        if (edgeDef == null)
                            //TODO a better exception here
                            throw new Exception("edge attribute not defined.");

                        if (edgeDef.Multiplicity == EdgeMultiplicity.SingleEdge)
                            //TODO a better exception here
                            throw new Exception("Add edges is only defined on hyper/multi edges.");

                        var edgeTypeID = edgeDef.ID;
                        StructuredPropertiesUpdate structuredUpdate;
                        UnstructuredPropertiesUpdate unstructuredUpdate;
                        IEnumerable<SingleEdgeUpdateDefinition> singleUpdate;

                        CheckIfToBeAddedElementAlreadyExist(myVertex, 
                                                            edgeDef, 
                                                            hyperEdge.Value,
                                                            myTransaction,
                                                            mySecurity);

                        CreateSingleEdgeUpdateDefinitions(source,
                                                            myTransaction,
                                                            mySecurity,
                                                            hyperEdge.Value,
                                                            edgeDef,
                                                            out structuredUpdate,
                                                            out unstructuredUpdate,
                                                            out singleUpdate);

                        toBeUpdatedHyper = toBeUpdatedHyper ?? new Dictionary<long, HyperEdgeUpdateDefinition>();

                        toBeUpdatedHyper.Add(edgeTypeID, new HyperEdgeUpdateDefinition(edgeTypeID, null, structuredUpdate, unstructuredUpdate, null, singleUpdate));
                    }
                }

                #endregion

                #region update RemovedElementsFromCollectionEdges

                if (myUpdate.RemovedElementsFromCollectionEdges != null)
                {
                    foreach (var hyperEdge in myUpdate.RemovedElementsFromCollectionEdges)
                    {
                        var edgeDef = myVertexType.GetOutgoingEdgeDefinition(hyperEdge.Key);

                        if (edgeDef == null)
                            //TODO a better exception here
                            throw new Exception("Edge attribute not defined.");

                        if (edgeDef.Multiplicity == EdgeMultiplicity.SingleEdge)
                            //TODO a better exception here
                            throw new Exception("Removing edges is only defined on hyper/multi edges.");

                        var edgeTypeID = edgeDef.ID;

                        var del = CreateSingleEdgeDeleteDefinitions(source, myTransaction, mySecurity, hyperEdge.Value, edgeDef);

                        toBeUpdatedHyper = toBeUpdatedHyper ?? new Dictionary<long, HyperEdgeUpdateDefinition>();
                        toBeUpdatedHyper.Add(edgeTypeID, new HyperEdgeUpdateDefinition(edgeTypeID, null, null, null, del, null));

                    }
                }

                #endregion
            }

            #endregion

            #region create updates

            var updateSingle = (toBeUpdatedSingle != null || toBeDeletedSingle != null)
                ? new SingleEdgeUpdate(toBeUpdatedSingle, toBeDeletedSingle)
                : null;

            var updateHyper = (toBeUpdatedHyper != null || toBeDeletedHyper != null)
                ? new HyperEdgeUpdate(toBeUpdatedHyper, toBeDeletedHyper)
                : null;

            var updateStructured = (toBeUpdatedStructured != null || toBeDeletedStructured != null)
                ? new StructuredPropertiesUpdate(toBeUpdatedStructured, toBeDeletedStructured)
                : null;

            var updateUnstructured = (toBeUpdatedUnstructured != null || toBeDeletedUnstructured != null)
                ? new UnstructuredPropertiesUpdate(toBeUpdatedUnstructured, toBeDeletedUnstructured)
                : null;

            var updateBinaries = (toBeUpdatedBinaries != null || toBeDeletedBinaries != null)
                ? new BinaryPropertiesUpdate(toBeUpdatedBinaries, toBeDeletedBinaries)
                : null;

            #endregion

            return Tuple.Create(revision,
                                edition,
                                new VertexUpdateDefinition(comment,
                                                            updateStructured,
                                                            updateUnstructured,
                                                            updateBinaries,
                                                            updateSingle,
                                                            updateHyper));
        }
Esempio n. 3
0
 private static void CheckAddBinaryProperties(RequestInsertVertex myInsertDefinition, IVertexType vertexType)
 {
     foreach (var prop in myInsertDefinition.BinaryProperties)
     {
         var propertyDef = vertexType.GetBinaryPropertyDefinition(prop.Key);
         if (propertyDef == null)
             throw new AttributeDoesNotExistException(prop.Key, myInsertDefinition.VertexTypeName);
     }
 }