Example #1
0
        /// <summary>
        /// Add an edge from one vertex (source) to another (sink)
        /// NOTE: Both the source and sink vertex are modified.
        /// NOTE: This function may upload the edge-document.
        /// NOTE: srcVertex and sinkVertex are updated and uploaded.
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="srcId"></param>
        /// <param name="sinkId"></param>
        /// <param name="srcVertexField"></param>
        /// <param name="sinkVertexField"></param>
        /// <param name="edgeJsonObject"></param>
        /// <param name="srcVertexObject"></param>
        /// <param name="sinkVertexObject"></param>
        /// <param name="outEdgeObject"></param>
        /// <param name="outEdgeDocID"></param>
        /// <param name="inEdgeObject"></param>
        /// <param name="inEdgeDocID"></param>
        public static void InsertEdgeAndUpload(
            GraphViewConnection connection,
            string srcId, string sinkId,
            VertexField srcVertexField, VertexField sinkVertexField,
            JObject edgeJsonObject,
            JObject srcVertexObject, JObject sinkVertexObject,
            out JObject outEdgeObject, out string outEdgeDocID,
            out JObject inEdgeObject, out string inEdgeDocID)
        {
            long edgeOffset = (long)srcVertexObject["_nextEdgeOffset"];

            srcVertexObject["_nextEdgeOffset"] = edgeOffset + 1;

            outEdgeObject = (JObject)edgeJsonObject.DeepClone();
            inEdgeObject  = (JObject)edgeJsonObject.DeepClone();

            // Add "id" property to edgeObject if desired
            if (connection.GenerateEdgeId)
            {
                string guid = GraphViewConnection.GenerateDocumentId();
                outEdgeObject["_edgeId"] = guid;
                inEdgeObject["_edgeId"]  = guid;
            }

            string srcLabel  = srcVertexObject["label"]?.ToString();
            string sinkLabel = sinkVertexObject["label"]?.ToString();

            GraphViewJsonCommand.UpdateEdgeMetaProperty(outEdgeObject, edgeOffset, false, sinkId, sinkLabel);
            GraphViewJsonCommand.UpdateEdgeMetaProperty(inEdgeObject, edgeOffset, true, srcId, srcLabel);

            InsertEdgeObjectInternal(connection, srcVertexObject, srcVertexField, outEdgeObject, false, out outEdgeDocID); // srcVertex uploaded
            InsertEdgeObjectInternal(connection, sinkVertexObject, sinkVertexField, inEdgeObject, true, out inEdgeDocID);  // sinkVertex uploaded
        }
Example #2
0
        internal override List <RawRecord> CrossApply(RawRecord record)
        {
            List <RawRecord> results = new List <RawRecord>();

            FieldObject target = record[this._targetIndex];

            if (target != null)
            {
                VertexField vertex = target as VertexField;
                if (vertex != null)
                {
                    RawRecord r = new RawRecord();
                    r.Append(new StringField(vertex.VertexMetaProperties[KW_DOC_ID].ToValue));
                    results.Add(r);
                }

                VertexSinglePropertyField vertexSingleProperty = target as VertexSinglePropertyField;
                if (vertexSingleProperty != null)
                {
                    RawRecord r = new RawRecord();
                    r.Append(new StringField(vertexSingleProperty.PropertyId));
                    results.Add(r);
                }

                EdgeField edge = target as EdgeField;
                if (edge != null)
                {
                    RawRecord r = new RawRecord();
                    r.Append(new StringField(edge.EdgeId));
                    results.Add(r);
                }
            }

            return(results);
        }
        internal override RawRecord DataModify(RawRecord record)
        {
            JObject vertexObject = this._vertexDocument;

            string vertexId = GraphViewConnection.GenerateDocumentId();

            Debug.Assert(vertexObject["id"] == null);
            Debug.Assert(vertexObject["_partition"] == null);
            vertexObject["id"]         = vertexId;
            vertexObject["_partition"] = vertexId;

            this.Connection.CreateDocumentAsync(vertexObject).Wait();

            VertexField vertexField = Connection.VertexCache.GetVertexField(vertexId, vertexObject);

            RawRecord result = new RawRecord();

            foreach (string fieldName in _projectedFieldList)
            {
                FieldObject fieldValue = vertexField[fieldName];

                result.Append(fieldValue);
            }

            return(result);
        }
Example #4
0
        public static void Run()
        {
            // Initialize scene object
            Scene scene = new Scene();

            // Initialize Node class object
            Node cubeNode = new Node("box");

            //ExStart:ConvertBoxMeshtoTriangleMeshCustomMemoryLayout
            // get mesh of the Box
            Mesh box = (new Box()).ToMesh();
            //create a customized vertex layout
            VertexDeclaration vd       = new VertexDeclaration();
            VertexField       position = vd.AddField(VertexFieldDataType.FVector4, VertexFieldSemantic.Position);

            vd.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Normal);
            // get a triangle mesh
            TriMesh triMesh = TriMesh.FromMesh(box);

            //ExEnd:ConvertBoxMeshtoTriangleMeshCustomMemoryLayout

            // Point node to the Mesh geometry
            cubeNode.Entity = box;

            // Add Node to a scene
            scene.RootNode.ChildNodes.Add(cubeNode);

            // The path to the documents directory.
            string MyDir = RunExamples.GetDataDir() + RunExamples.GetOutputFilePath("BoxToTriangleMeshCustomMemoryLayoutScene.fbx");

            // Save 3D scene in the supported file formats
            scene.Save(MyDir, FileFormat.FBX7400ASCII);

            Console.WriteLine("\n Converted a Box mesh to triangle mesh with custom memory layout of the vertex successfully.\nFile saved at " + MyDir);
        }
        private void DropVertexSingleProperty(VertexSinglePropertyField vp)
        {
            // Update DocDB
            VertexField vertexField  = vp.VertexProperty.Vertex;
            JObject     vertexObject = this.connection.RetrieveDocumentById(vertexField.VertexId);

            Debug.Assert(vertexObject[vp.PropertyName] != null);

            JArray vertexProperty = (JArray)vertexObject[vp.PropertyName];

            vertexProperty
            .First(singleProperty => (string)singleProperty["_propId"] == vp.PropertyId)
            .Remove();
            if (vertexObject.Count == 0)
            {
                vertexProperty.Remove();
            }

            this.connection.ReplaceOrDeleteDocumentAsync(vertexField.VertexId, vertexObject, (string)vertexObject["_partition"]).Wait();

            // Update vertex field
            VertexPropertyField vertexPropertyField = vertexField.VertexProperties[vp.PropertyName];
            bool found = vertexPropertyField.Multiples.Remove(vp.PropertyId);

            Debug.Assert(found);
            if (!vertexPropertyField.Multiples.Any())
            {
                vertexField.VertexProperties.Remove(vp.PropertyName);
            }
        }
 public DeltaEdgeField(EdgeField outEdgeField, VertexField srcVertexField, EdgeField inEdgeField, VertexField sinkVertexField, bool useReverseEdges)
 {
     this.outEdgeField    = outEdgeField;
     this.inEdgeField     = inEdgeField;
     this.srcVertexField  = srcVertexField;
     this.sinkVertexField = sinkVertexField;
     this.UseReverseEdges = useReverseEdges;
     this.deltaProperties = new Dictionary <string, Tuple <EdgeDeltaType, JValue> >();
 }
        private void UpdatePropertiesOfVertex(VertexField vertex)
        {
            JObject vertexDocument = this.Connection.RetrieveDocumentById(vertex.VertexId);

            foreach (WPropertyExpression property in this.updateProperties)
            {
                Debug.Assert(property.Value != null);

                VertexPropertyField vertexProperty;
                string name = property.Key.Value;

                // Construct single property
                JObject meta = new JObject();
                foreach (KeyValuePair <WValueExpression, WValueExpression> pair in property.MetaProperties)
                {
                    meta[pair.Key.Value] = pair.Value.ToJValue();
                }
                JObject singleProperty = new JObject {
                    ["_value"]  = property.Value.ToJValue(),
                    ["_propId"] = GraphViewConnection.GenerateDocumentId(),
                    ["_meta"]   = meta,
                };

                // Set / Append to multiProperty
                JArray multiProperty;
                if (vertexDocument[name] == null)
                {
                    multiProperty        = new JArray();
                    vertexDocument[name] = multiProperty;
                }
                else
                {
                    multiProperty = (JArray)vertexDocument[name];
                }

                if (property.Cardinality == GremlinKeyword.PropertyCardinality.single)
                {
                    multiProperty.Clear();
                }
                multiProperty.Add(singleProperty);

                // Update vertex field
                bool existed = vertex.VertexProperties.TryGetValue(name, out vertexProperty);
                if (!existed)
                {
                    vertexProperty = new VertexPropertyField(vertexDocument.Property(name), vertex);
                    vertex.VertexProperties.Add(name, vertexProperty);
                }
                else
                {
                    vertexProperty.Replace(vertexDocument.Property(name));
                }
            }

            // Upload to DocDB
            this.Connection.ReplaceOrDeleteDocumentAsync(vertex.VertexId, vertexDocument, (string)vertexDocument["_partition"]).Wait();
        }
Example #8
0
        public List <VertexField> GetVerticesByIds(HashSet <string> vertexId, GraphViewCommand command, string partition,
                                                   bool constructEdges = false)
        {
            const string NODE_ALIAS = "node";
            var          jsonQuery  = new JsonQuery
            {
                NodeAlias      = NODE_ALIAS,
                RawWhereClause = new WBooleanComparisonExpression
                {
                    ComparisonType = BooleanComparisonType.Equals,
                    FirstExpr      = new WColumnReferenceExpression(NODE_ALIAS, DocumentDBKeywords.KW_EDGEDOC_IDENTIFIER),
                    SecondExpr     = new WValueExpression("null")
                }
            };

            // SELECT node
            jsonQuery.AddSelectElement(NODE_ALIAS);
            jsonQuery.FlatProperties.Add(DocumentDBKeywords.KW_EDGEDOC_IDENTIFIER);

            jsonQuery.WhereConjunction(new WInPredicate(
                                           new WColumnReferenceExpression(NODE_ALIAS, GremlinKeyword.NodeID),
                                           vertexId.ToList()), BooleanBinaryExpressionType.And);

            if (partition != null)
            {
                jsonQuery.WhereConjunction(new WBooleanComparisonExpression
                {
                    ComparisonType = BooleanComparisonType.Equals,
                    FirstExpr      = new WValueExpression($"{NODE_ALIAS}{command.Connection.GetPartitionPathIndexer()}", false),
                    SecondExpr     = new WValueExpression(partition, true)
                }, BooleanBinaryExpressionType.And);
            }

            jsonQuery.NodeProperties = new List <string> {
                "node", "*"
            };
            jsonQuery.EdgeProperties = new List <string>();

            IEnumerator <Tuple <VertexField, RawRecord> > queryResult = this.GetVerticesAndEdgesViaVertices(jsonQuery, command);

            List <VertexField> result = new List <VertexField>();

            while (queryResult.MoveNext())
            {
                VertexField vertex = queryResult.Current.Item1;
                result.Add(vertex);
            }

            if (constructEdges)
            {
                // TODO: need double check on JsonServer
                EdgeDocumentHelper.ConstructLazyAdjacencyList(command, EdgeType.Both, vertexId, new HashSet <string>());
            }

            return(result);
        }
        private void DropVertex(VertexField vertexField)
        {
            RawRecord record = new RawRecord();

            record.Append(new StringField(vertexField.VertexId));  // nodeIdIndex
            DropNodeOperator op = new DropNodeOperator(this.dummyInputOp, this.connection, 0);

            op.DataModify(record);

            // Now VertexCacheObject has been updated (in DataModify)
        }
Example #10
0
        public VertexField GetVertexField(string vertexId)
        {
            VertexField result;

            if (!this._cachedVertexField.TryGetValue(vertexId, out result))
            {
                JObject vertexObject = this.Connection.RetrieveDocumentById(vertexId);
                result = new VertexField(this.Connection, vertexObject);
                this._cachedVertexField.Add(vertexId, result);
            }
            return(result);
        }
Example #11
0
        private void UpdateNodeProperties(
            Dictionary <string, JObject> documentsMap,
            string vertexId,
            JObject vertexDocObject,
            List <Tuple <WValueExpression, WValueExpression, int> > propList,
            UpdatePropertyMode mode)
        {
            VertexField vertexField = this.Connection.VertexCache.GetVertexField(vertexId);

            // Drop all non-reserved properties
            if (propList.Count == 1 &&
                !propList[0].Item1.SingleQuoted &&
                propList[0].Item1.Value.Equals("*", StringComparison.OrdinalIgnoreCase) &&
                !propList[0].Item2.SingleQuoted &&
                propList[0].Item2.Value.Equals("null", StringComparison.OrdinalIgnoreCase))
            {
                List <string> toBeDroppedPropertiesNames = GraphViewJsonCommand.DropAllNodeProperties(vertexDocObject);
                foreach (var propertyName in toBeDroppedPropertiesNames)
                {
                    vertexField.VertexProperties.Remove(propertyName);
                }
            }
            else
            {
                foreach (var t in propList)
                {
                    WValueExpression keyExpression   = t.Item1;
                    WValueExpression valueExpression = t.Item2;

                    if (mode == UpdatePropertyMode.Set)
                    {
                        JProperty updatedProperty = GraphViewJsonCommand.UpdateProperty(vertexDocObject, keyExpression, valueExpression);
                        if (updatedProperty == null)
                        {
                            vertexField.VertexProperties.Remove(keyExpression.Value);
                        }
                        else
                        {
                            vertexField.UpdateVertexProperty(updatedProperty.Name, updatedProperty.Value.ToString(),
                                                             JsonDataTypeHelper.GetJsonDataType(updatedProperty.Value.Type));
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }

            documentsMap[vertexId] = vertexDocObject;
        }
        // TODO: Batch upload for the DropEdge part
        internal override RawRecord DataModify(RawRecord record)
        {
            string vertexId = record[this._nodeIdIndex].ToValue;

            // Temporarily change
            DropEdgeOperator dropEdgeOp = new DropEdgeOperator(null, this.Connection, 0, 1);
            RawRecord        temp       = new RawRecord(2);

            VertexField vertex = this.Connection.VertexCache.GetVertexField(vertexId);

            // Save a copy of Edges _IDs & drop outgoing edges
            List <long> outEdgeOffsets = vertex.AdjacencyList.AllEdges.Select(e => e.Offset).ToList();

            foreach (long outEdgeOffset in outEdgeOffsets)
            {
                temp.fieldValues[0] = new StringField(vertexId);
                temp.fieldValues[1] = new StringField(outEdgeOffset.ToString());
                dropEdgeOp.DataModify(temp);
            }

            AdjacencyListField revAdjacencyListField = Connection.UseReverseEdges
                                                       ? vertex.RevAdjacencyList
                                                       : EdgeDocumentHelper.GetReverseAdjacencyListOfVertex(Connection, vertexId);
            // Save a copy of incoming Edges <srcVertexId, edgeOffsetInSrcVertex> & drop them
            List <Tuple <string, long> > inEdges = revAdjacencyListField.AllEdges.Select(
                e => new Tuple <string, long>(e.OutV, e.Offset)).ToList();

            foreach (var inEdge in inEdges)
            {
                temp.fieldValues[0] = new StringField(inEdge.Item1);            // srcVertexId
                temp.fieldValues[1] = new StringField(inEdge.Item2.ToString()); // edgeOffsetInSrcVertex
                dropEdgeOp.DataModify(temp);
            }

            // Delete the node-document!
#if DEBUG
            JObject vertexObject = this.Connection.RetrieveDocumentById(vertexId);
            Debug.Assert(vertexObject != null);
            Debug.Assert(vertexObject["_edge"] is JArray);
            Debug.Assert(((JArray)vertexObject["_edge"]).Count == 0);
            Debug.Assert(vertexObject["_reverse_edge"] is JArray);
            Debug.Assert(((JArray)vertexObject["_reverse_edge"]).Count == 0);
#endif
            // NOTE: for vertex document, id = _partition
            this.Connection.ReplaceOrDeleteDocumentAsync(vertexId, null, vertexId).Wait();

            // Update VertexCache
            this.Connection.VertexCache.TryRemoveVertexField(vertexId);

            return(null);
        }
        internal override RawRecord DataModify(RawRecord record)
        {
            string srcId      = record[this._srcIdIndex].ToValue;
            long   edgeOffset = long.Parse(record[this._edgeOffsetIndex].ToValue);

            JObject srcEdgeObject;
            string  srcEdgeDocId, sinkEdgeDocId;
            JObject srcVertexObject = this.Connection.RetrieveDocumentById(srcId);

            EdgeDocumentHelper.FindEdgeBySourceAndOffset(
                this.Connection, srcVertexObject, srcId, edgeOffset, false,
                out srcEdgeObject, out srcEdgeDocId);
            if (srcEdgeObject == null)
            {
                //TODO: Check is this condition alright?
                return(null);
            }

            string  sinkId = (string)srcEdgeObject["_sinkV"];
            JObject sinkVertexObject;

            if (!string.Equals(sinkId, srcId))
            {
                sinkVertexObject = this.Connection.RetrieveDocumentById(sinkId);
                JObject sinkEdgeObject;
                EdgeDocumentHelper.FindEdgeBySourceAndOffset(
                    this.Connection, sinkVertexObject, srcId, edgeOffset, true,
                    out sinkEdgeObject, out sinkEdgeDocId);
            }
            else
            {
                sinkVertexObject = srcVertexObject;  // NOTE: Must not use DeepClone() here!
                sinkEdgeDocId    = srcEdgeDocId;
            }

            Dictionary <string, Tuple <JObject, string> > uploadDocuments = new Dictionary <string, Tuple <JObject, string> >();

            EdgeDocumentHelper.RemoveEdge(uploadDocuments, this.Connection, srcEdgeDocId, srcVertexObject, false, srcId, edgeOffset);
            EdgeDocumentHelper.RemoveEdge(uploadDocuments, this.Connection, sinkEdgeDocId, sinkVertexObject, true, srcId, edgeOffset);
            this.Connection.ReplaceOrDeleteDocumentsAsync(uploadDocuments).Wait();


            VertexField srcVertexField  = this.Connection.VertexCache.GetVertexField(srcId, srcVertexObject);
            VertexField sinkVertexField = this.Connection.VertexCache.GetVertexField(sinkId, sinkVertexObject);

            srcVertexField.AdjacencyList.RemoveEdgeField(srcId, edgeOffset);
            sinkVertexField.RevAdjacencyList.RemoveEdgeField(srcId, edgeOffset);

            return(null);
        }
        internal override RawRecord DataModify(RawRecord record)
        {
            FieldObject dropTarget = record[this.dropTargetIndex];

            VertexField vertexField = dropTarget as VertexField;;

            if (vertexField != null)
            {
                this.DropVertex(vertexField);
                return(null);
            }

            EdgeField edgeField = dropTarget as EdgeField;

            if (edgeField != null)
            {
                this.DropEdge(edgeField);
                return(null);
            }

            PropertyField property = dropTarget as PropertyField;

            if (property != null)
            {
                if (property is VertexPropertyField)
                {
                    this.DropVertexProperty((VertexPropertyField)property);
                }
                else if (property is VertexSinglePropertyField)
                {
                    this.DropVertexSingleProperty((VertexSinglePropertyField)property);
                }
                else if (property is EdgePropertyField)
                {
                    this.DropEdgeProperty((EdgePropertyField)property);
                }
                else
                {
                    this.DropVertexPropertyMetaProperty((ValuePropertyField)property);
                }

                return(null);
            }

            //
            // Should not reach here
            //
            throw new Exception("BUG: Should not get here");
            return(null);
        }
        private void DropVertexProperty(VertexPropertyField vp)
        {
            // Update DocDB
            VertexField vertexField  = vp.Vertex;
            JObject     vertexObject = this.connection.RetrieveDocumentById(vertexField.VertexId);

            Debug.Assert(vertexObject[vp.PropertyName] != null);
            vertexObject[vp.PropertyName].Remove();

            this.connection.ReplaceOrDeleteDocumentAsync(vertexField.VertexId, vertexObject, (string)vertexObject["_partition"]).Wait();

            // Update vertex field
            vertexField.VertexProperties.Remove(vp.PropertyName);
        }
Example #16
0
        public JObject ConstructNodeJsonDocument(out List <string> projectedFieldList)
        {
            JObject nodeJsonDocument = new JObject();

            projectedFieldList = new List <string>(GraphViewReservedProperties.ReservedNodeProperties);

            for (var i = 0; i < Parameters.Count; i += 2)
            {
                var key = (Parameters[i] as WValueExpression).Value;

                //GraphViewJsonCommand.UpdateProperty(nodeJsonDocument, Parameters[i] as WValueExpression,
                //    Parameters[i + 1] as WValueExpression);
                GraphViewJsonCommand.UpdateProperty(nodeJsonDocument, Parameters[i] as WValueExpression,
                                                    Parameters[i + 1] as WValueExpression);
                string name  = (Parameters[i] as WValueExpression).Value;
                JToken value = (Parameters[i + 1] as WValueExpression).ToJValue();
                if (value != null)
                {
                    if (VertexField.IsVertexMetaProperty(name))
                    {
                        nodeJsonDocument[name] = value;
                    }
                    else
                    {
                        nodeJsonDocument[name] = new JArray {
                            new JObject {
                                ["_value"]  = value,
                                ["_propId"] = GraphViewConnection.GenerateDocumentId(),
                                ["_meta"]   = new JObject(),
                            },
                        };
                    }
                }

                if (!projectedFieldList.Contains(key))
                {
                    projectedFieldList.Add(key);
                }
            }

            //nodeJsonDocument = GraphViewJsonCommand.insert_property(nodeJsonDocument, "[]", "_edge").ToString();
            //nodeJsonDocument = GraphViewJsonCommand.insert_property(nodeJsonDocument, "[]", "_reverse_edge").ToString();
            nodeJsonDocument["_edge"]           = new JArray();
            nodeJsonDocument["_reverse_edge"]   = new JArray();
            nodeJsonDocument["_nextEdgeOffset"] = 0;

            return(nodeJsonDocument);
        }
Example #17
0
        internal void AddOrUpdateVertexDelta(VertexField vertexField, DeltaLog log)
        {
            string           vertexId = vertexField.VertexId;
            DeltaVertexField delta;

            if (vertexDelta.ContainsKey(vertexId))
            {
                delta = vertexDelta[vertexId];
            }
            else
            {
                delta = new DeltaVertexField(vertexField);
                vertexDelta.Add(vertexId, delta);
            }
            delta.AddDeltaLog(log);
        }
Example #18
0
        internal void AddOrUpdateEdgeDelta(EdgeField outEdgeField, VertexField srcVertexField,
                                           EdgeField inEdgeField, VertexField sinkVertexField, DeltaLog log, bool useReverseEdges)
        {
            string edgeId = outEdgeField.EdgeId;

            DeltaEdgeField delta;

            if (edgeDelta.ContainsKey(edgeId))
            {
                delta = edgeDelta[edgeId];
            }
            else
            {
                delta             = new DeltaEdgeField(outEdgeField, srcVertexField, inEdgeField, sinkVertexField, useReverseEdges);
                edgeDelta[edgeId] = delta;
            }
            delta.AddDeltaLog(log);
        }
        internal override RawRecord DataModify(RawRecord record)
        {
            FieldObject updateTarget = record[this.updateTargetIndex];

            VertexField vertex = updateTarget as VertexField;;

            if (vertex != null)
            {
                this.UpdatePropertiesOfVertex(vertex);

                return(record);
            }

            EdgeField edge = updateTarget as EdgeField;

            if (edge != null)
            {
                this.UpdatePropertiesOfEdge(edge);

                return(record);
            }

            PropertyField property = updateTarget as PropertyField;

            if (property != null)
            {
                if (property is VertexSinglePropertyField)
                {
                    this.UpdateMetaPropertiesOfSingleVertexProperty((VertexSinglePropertyField)property);
                }
                else
                {
                    throw new GraphViewException($"BUG: updateTarget is {nameof(PropertyField)}: {property.GetType()}");
                }

                return(record);
            }

            //
            // Should not reach here
            //
            throw new Exception("BUG: Should not get here!");
        }
Example #20
0
        public VertexField AddOrUpdateVertexField(string vertexId, JObject vertexObject)
        {
            VertexField vertexField;

            if (this._cachedVertexField.TryGetValue(vertexId, out vertexField))
            {
                // TODO: Update?
            }
            else
            {
                //
                // Update saved etags when Constructing a vertex field
                // NOTE: For each vertex document, only ONE VertexField will be constructed ever.
                //
                this.SaveCurrentEtagNoOverride(vertexObject);

                vertexField = new VertexField(this.Connection, vertexObject);
                this._cachedVertexField.Add(vertexId, vertexField);
            }
            return(vertexField);
        }
        private void DropVertexPropertyMetaProperty(ValuePropertyField metaProperty)
        {
            Debug.Assert(metaProperty.Parent is VertexSinglePropertyField);
            VertexSinglePropertyField vertexSingleProperty = (VertexSinglePropertyField)metaProperty.Parent;

            VertexField vertexField  = vertexSingleProperty.VertexProperty.Vertex;
            JObject     vertexObject = this.connection.RetrieveDocumentById(vertexField.VertexId);

            Debug.Assert(vertexObject[vertexSingleProperty.PropertyName] != null);

            JToken propertyJToken = ((JArray)vertexObject[vertexSingleProperty.PropertyName])
                                    .First(singleProperty => (string)singleProperty["_propId"] == vertexSingleProperty.PropertyId);

            JObject metaPropertyJObject = (JObject)propertyJToken?["_meta"];

            metaPropertyJObject?.Property(metaProperty.PropertyName)?.Remove();

            // Update DocDB
            this.connection.ReplaceOrDeleteDocumentAsync(vertexField.VertexId, vertexObject, (string)vertexObject["_partition"]).Wait();

            // Update vertex field
            vertexSingleProperty.MetaProperties.Remove(metaProperty.PropertyName);
        }
Example #22
0
        public override FieldObject Evaluate(RawRecord record)
        {
            FieldObject checkObject = record[_checkFieldIndex];

            VertexField vertexField = checkObject as VertexField;
            EdgeField   edgeField   = checkObject as EdgeField;

            if (vertexField != null)
            {
                if (vertexField.AllProperties.Count(pf => pf.PropertyName == _propertyName) > 0)
                {
                    return(new StringField("true", JsonDataType.Boolean));
                }
                else
                {
                    return(new StringField("false", JsonDataType.Boolean));
                }
            }
            else if (edgeField != null)
            {
                if (edgeField.EdgeProperties.ContainsKey(_propertyName))
                {
                    return(new StringField("true", JsonDataType.Boolean));
                }
                else
                {
                    return(new StringField("false", JsonDataType.Boolean));
                }
            }
            else
            {
                throw new GraphViewException(
                          "HasProperty() function can only be applied to a VertexField or EdgeField but now the object is " +
                          checkObject.GetType());
            }
        }
Example #23
0
        /// <summary>
        /// Add an edge from one vertex (source) to another (sink)
        /// NOTE: Both the source and sink vertex are modified.
        /// NOTE: This function may upload the edge-document.
        /// NOTE: srcVertex and sinkVertex are updated and uploaded.
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="srcId"></param>
        /// <param name="sinkId"></param>
        /// <param name="srcVertexField"></param>
        /// <param name="sinkVertexField"></param>
        /// <param name="edgeJsonObject"></param>
        /// <param name="srcVertexObject"></param>
        /// <param name="sinkVertexObject"></param>
        /// <param name="outEdgeObject"></param>
        /// <param name="outEdgeDocID"></param>
        /// <param name="inEdgeObject"></param>
        /// <param name="inEdgeDocID"></param>
        public static void InsertEdgeAndUpload(
            GraphViewConnection connection,
            string srcId, string sinkId,
            VertexField srcVertexField, VertexField sinkVertexField,
            JObject edgeJsonObject,
            JObject srcVertexObject, JObject sinkVertexObject,
            out JObject outEdgeObject, out string outEdgeDocID,
            out JObject inEdgeObject, out string inEdgeDocID)
        {
            //long edgeOffset = (long)srcVertexObject[KW_VERTEX_NEXTOFFSET];
            //srcVertexObject[KW_VERTEX_NEXTOFFSET] = edgeOffset + 1;

            outEdgeObject = (JObject)edgeJsonObject.DeepClone();
            inEdgeObject  = (JObject)edgeJsonObject.DeepClone();

            // Add "id" property to edgeObject
            string edgeId = GraphViewConnection.GenerateDocumentId();

            string srcLabel  = srcVertexObject[KW_VERTEX_LABEL]?.ToString();
            string sinkLabel = sinkVertexObject[KW_VERTEX_LABEL]?.ToString();

            GraphViewJsonCommand.UpdateEdgeMetaProperty(outEdgeObject, edgeId, false, sinkId, sinkLabel);
            GraphViewJsonCommand.UpdateEdgeMetaProperty(inEdgeObject, edgeId, true, srcId, srcLabel);

            InsertEdgeObjectInternal(connection, srcVertexObject, srcVertexField, outEdgeObject, false, out outEdgeDocID); // srcVertex uploaded

            if (connection.UseReverseEdges)
            {
                InsertEdgeObjectInternal(connection, sinkVertexObject, sinkVertexField, inEdgeObject, true,
                                         out inEdgeDocID); // sinkVertex uploaded
            }
            else
            {
                inEdgeDocID = EdgeDocumentHelper.VirtualReverseEdgeDocId;
            }
        }
Example #24
0
        /// <summary>
        /// Insert edgeObject to one a vertex.
        /// NOTE: vertex-document and edge-document(s) are uploaded.
        /// NOTE: If changing _edge/_reverse_edge field from JArray to JObject, the "EdgeDocId" of existing
        ///       edges in VertexCache are updated (from null to the newly created edge-document's id)
        /// NOTE: Adding the newly created edge into VertexCache is not operated by this function. Actually,
        ///       if called by <see cref="UpdateEdgeProperty"/>, VertexCache should be updated by setting an
        ///       edge's property, but not adding a new edge.
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="vertexObject"></param>
        /// <param name="vertexField">Can be null if we already know edgeContainer is JObject</param>
        /// <param name="edgeObject"></param>
        /// <param name="isReverse"></param>
        /// <param name="newEdgeDocId"></param>
        private static void InsertEdgeObjectInternal(
            GraphViewConnection connection,
            JObject vertexObject,
            VertexField vertexField,
            JObject edgeObject,
            bool isReverse,
            out string newEdgeDocId)
        {
            bool   tooLarge;
            JToken edgeContainer = vertexObject[isReverse ? "_reverse_edge" : "_edge"]; // JArray or JObject

            if (edgeContainer is JObject)
            {
                // Now it is a large-degree vertex, and contains at least 1 edge-document
                JArray edgeDocumentsArray = (JArray)edgeContainer["_edges"];
                Debug.Assert(edgeDocumentsArray != null, "edgeDocuments != null");
                Debug.Assert(edgeDocumentsArray.Count > 0, "edgeDocuments.Count > 0");

                string  lastEdgeDocId = (string)edgeDocumentsArray.Last["id"];
                JObject edgeDocument  = connection.RetrieveDocumentById(lastEdgeDocId);
                Debug.Assert(((string)edgeDocument["id"]).Equals(lastEdgeDocId), "((string)edgeDocument['id']).Equals(lastEdgeDocId)");
                Debug.Assert((bool)edgeDocument["_is_reverse"] == isReverse, "(bool)edgeDocument['_is_reverse'] == isReverse");
                Debug.Assert((string)edgeDocument["_vertex_id"] == (string)vertexObject["id"], "(string)edgeDocument['_vertex_id'] == (string)vertexObject['id']");

                JArray edgesArray = (JArray)edgeDocument["_edge"];
                Debug.Assert(edgesArray != null, "edgesArray != null");
                Debug.Assert(edgesArray.Count > 0, "edgesArray.Count > 0");

                if (connection.EdgeSpillThreshold == 0)
                {
                    // Don't spill an edge-document until it is too large
                    edgesArray.Add(edgeObject);
                    tooLarge = false;
                }
                else
                {
                    // Explicitly specified a threshold
                    Debug.Assert(connection.EdgeSpillThreshold > 0, "connection.EdgeSpillThreshold > 0");
                    if (edgesArray.Count >= connection.EdgeSpillThreshold)
                    {
                        // The threshold is reached!
                        tooLarge = true;
                    }
                    else
                    {
                        // The threshold is not reached
                        edgesArray.Add(edgeObject);
                        tooLarge = false;
                    }
                }

                // If the edge-document is not too large (reach the threshold), try to
                //   upload the edge into the document
                if (!tooLarge)
                {
                    UploadOne(connection, lastEdgeDocId, edgeDocument, out tooLarge);
                }
                if (tooLarge)
                {
                    // The edge is too large to be filled into the last edge-document
                    // or the threashold is reached:
                    // Create a new edge-document to store the edge.
                    JObject edgeDocObject = new JObject {
                        ["id"]          = GraphViewConnection.GenerateDocumentId(),
                        ["_partition"]  = vertexObject["_partition"],
                        ["_is_reverse"] = isReverse,
                        ["_vertex_id"]  = (string)vertexObject["id"],
                        ["_edge"]       = new JArray(edgeObject)
                    };
                    lastEdgeDocId = connection.CreateDocumentAsync(edgeDocObject).Result;

                    // Add the newly create edge-document to vertexObject & upload the vertexObject
                    edgeDocumentsArray.Add(new JObject {
                        ["id"] = lastEdgeDocId
                    });
                }
                newEdgeDocId = lastEdgeDocId;

                // Upload the vertex documention (at least, its _nextXxx is changed)
                bool dummyTooLarge;
                UploadOne(connection, (string)vertexObject["id"], vertexObject, out dummyTooLarge);
                Debug.Assert(!dummyTooLarge);
            }
            else if (edgeContainer is JArray)
            {
                ((JArray)edgeContainer).Add(edgeObject);
                if (connection.EdgeSpillThreshold == 0)
                {
                    // Don't spill an edge-document until it is too large
                    tooLarge = false;
                }
                else
                {
                    // Explicitly specified a threshold
                    Debug.Assert(connection.EdgeSpillThreshold > 0, "connection.EdgeSpillThreshold > 0");
                    tooLarge = (((JArray)edgeContainer).Count >= connection.EdgeSpillThreshold);
                }

                if (!tooLarge)
                {
                    UploadOne(connection, (string)vertexObject["id"], vertexObject, out tooLarge);
                }
                if (tooLarge)
                {
                    string existEdgeDocId;
                    SpillVertexEdgesToDocument(connection, vertexObject, out existEdgeDocId, out newEdgeDocId);

                    // Update the in & out edges in vertex field
                    if (isReverse)
                    {
                        Debug.Assert(vertexField.RevAdjacencyList.AllEdges.All(edge => edge.EdgeDocID == null));
                        foreach (EdgeField edge in vertexField.RevAdjacencyList.AllEdges)
                        {
                            edge.EdgeDocID = existEdgeDocId;
                        }
                    }
                    else
                    {
                        Debug.Assert(vertexField.AdjacencyList.AllEdges.All(edge => edge.EdgeDocID == null));
                        foreach (EdgeField edge in vertexField.AdjacencyList.AllEdges)
                        {
                            edge.EdgeDocID = existEdgeDocId;
                        }
                    }
                }
                else
                {
                    newEdgeDocId = null;
                }
            }
            else
            {
                throw new Exception($"BUG: edgeContainer should either be JObject or JArray, but now: {edgeContainer?.GetType()}");
            }
        }
Example #25
0
        public IEnumerator <Tuple <VertexField, RawRecord> > GetVerticesAndEdgesViaVertices(JsonQuery vertexQuery,
                                                                                            GraphViewCommand command)
        {
            IEnumerable <JObject> items          = this.ExecuteQueryScript(vertexQuery);
            List <string>         nodeProperties = new List <string>(vertexQuery.NodeProperties);
            List <string>         edgeProperties = new List <string>(vertexQuery.EdgeProperties);

            string nodeAlias = nodeProperties[0];

            // Skip i = 0, which is the (node.* as nodeAlias) field
            nodeProperties.RemoveAt(0);

            //
            // TODO: Refactor
            //
            string edgeAlias    = null;
            bool   isReverseAdj = false;
            bool   isStartVertexTheOriginVertex = false;
            bool   crossApplyEdgeOnServer       = edgeProperties.Any();

            if (crossApplyEdgeOnServer)
            {
                edgeAlias    = edgeProperties[0];
                isReverseAdj = bool.Parse(edgeProperties[1]);
                isStartVertexTheOriginVertex = bool.Parse(edgeProperties[2]);
                edgeProperties.RemoveAt(0);
                edgeProperties.RemoveAt(0);
                edgeProperties.RemoveAt(0);
            }

            //
            // Batch strategy:
            //  - For "small" vertexes, they have been cross applied on the server side
            //  - For "large" vertexes, just return the VertexField, the adjacency list decoder will
            //    construct spilled adjacency lists in batch mode and cross apply edges after that
            //
            Func <VertexField, string, Tuple <VertexField, RawRecord> > makeCrossAppliedRecord = (vertexField, edgeId) => {
                Debug.Assert(vertexField != null);

                RawRecord nodeRecord = new RawRecord();
                //
                // Fill node property field
                //
                foreach (string propertyName in nodeProperties)
                {
                    FieldObject propertyValue = vertexField[propertyName];
                    nodeRecord.Append(propertyValue);
                }

                RawRecord edgeRecord = new RawRecord(edgeProperties.Count);

                EdgeField edgeField =
                    ((AdjacencyListField)vertexField[isReverseAdj ? DocumentDBKeywords.KW_VERTEX_REV_EDGE : DocumentDBKeywords.KW_VERTEX_EDGE])
                    .GetEdgeField(edgeId, true);

                string startVertexId = vertexField.VertexId;
                AdjacencyListDecoder.FillMetaField(edgeRecord, edgeField, startVertexId, vertexField.Partition, isStartVertexTheOriginVertex, isReverseAdj);
                AdjacencyListDecoder.FillPropertyField(edgeRecord, edgeField, edgeProperties);

                nodeRecord.Append(edgeRecord);
                return(new Tuple <VertexField, RawRecord>(vertexField, nodeRecord));
            };

            Func <VertexField, Tuple <VertexField, RawRecord> > makeRawRecord = (vertexField) => {
                Debug.Assert(vertexField != null);

                RawRecord rawRecord = new RawRecord();
                //
                // Fill node property field
                //
                foreach (string propertyName in nodeProperties)
                {
                    FieldObject propertyValue = vertexField[propertyName];
                    rawRecord.Append(propertyValue);
                }
                return(new Tuple <VertexField, RawRecord>(vertexField, rawRecord));
            };

            HashSet <string> uniqueVertexIds = new HashSet <string>();
            HashSet <string> uniqueEdgeIds   = new HashSet <string>();

            foreach (JObject dynamicItem in items)
            {
                JObject tmpVertexObject = (JObject)((JObject)dynamicItem)[nodeAlias];
                string  vertexId        = (string)tmpVertexObject[DocumentDBKeywords.KW_DOC_ID];

                if (crossApplyEdgeOnServer)
                {
                    // Note: since vertex properties can be multi-valued,
                    // a DocumentDB query needs a join clause in the FROM clause
                    // to retrieve vertex property values, which may result in
                    // the same vertex being returned multiple times.
                    // We use the hash set uniqueVertexIds to ensure one vertex is
                    // produced only once.
                    if (EdgeDocumentHelper.IsBuildingTheAdjacencyListLazily(
                            tmpVertexObject,
                            isReverseAdj,
                            this.Connection.UseReverseEdges) &&
                        uniqueVertexIds.Add(vertexId))
                    {
                        VertexField vertexField = command.VertexCache.AddOrUpdateVertexField(vertexId, tmpVertexObject);
                        yield return(makeRawRecord(vertexField));
                    }
                    else // When the DocumentDB query crosses apply edges
                    {
                        JObject edgeObjct = (JObject)((JObject)dynamicItem)[edgeAlias];
                        string  edgeId    = (string)edgeObjct[DocumentDBKeywords.KW_EDGE_ID];

                        if (uniqueEdgeIds.Add(edgeId))
                        {
                            VertexField vertexField = command.VertexCache.AddOrUpdateVertexField(vertexId, tmpVertexObject);
                            yield return(makeCrossAppliedRecord(vertexField, edgeId));
                        }
                    }
                }
                else
                {
                    if (!uniqueVertexIds.Add(vertexId))
                    {
                        continue;
                    }
                    VertexField vertexField = command.VertexCache.AddOrUpdateVertexField(vertexId, tmpVertexObject);
                    yield return(makeRawRecord(vertexField));
                }
            }
        }
Example #26
0
        public IEnumerator <RawRecord> GetVerticesAndEdgesViaEdges(JsonQuery edgeQuery, GraphViewCommand command)
        {
            IEnumerable <JObject> items          = this.ExecuteQueryScript(edgeQuery);
            List <string>         nodeProperties = new List <string>(edgeQuery.NodeProperties);
            List <string>         edgeProperties = new List <string>(edgeQuery.EdgeProperties);

            string nodeAlias = nodeProperties[0];

            nodeProperties.RemoveAt(0);

            string edgeAlias = edgeProperties[0];

            edgeProperties.RemoveAt(0);

            HashSet <string> spilledVertexIdSet        = new HashSet <string>();
            HashSet <string> spilledVertexPartitionSet = new HashSet <string>();
            //
            // <vertex id, edge id>
            //
            Dictionary <string, List <string> > vertexIdAndEdgeIdsDict = new Dictionary <string, List <string> >();
            //
            // <vertex id, <edgeDocumentId, edgeObject>>
            //
            Dictionary <string, List <Tuple <string, JObject> > > vertexIdAndEdgeObjectsDict =
                new Dictionary <string, List <Tuple <string, JObject> > >();

            foreach (JObject dynamicItem in items)
            {
                JObject tmpObject  = (JObject)dynamicItem[nodeAlias];
                JObject edgeObject = (JObject)dynamicItem[edgeAlias];
                //
                // This is a spilled edge document
                //
                if (tmpObject[DocumentDBKeywords.KW_EDGEDOC_VERTEXID] != null)
                {
                    string vertexId = tmpObject[DocumentDBKeywords.KW_EDGEDOC_VERTEXID].ToString();
                    spilledVertexIdSet.Add(vertexId);
                    string partition = this.Connection.GetDocumentPartition(tmpObject);
                    if (partition != null)
                    {
                        spilledVertexPartitionSet.Add(partition);
                    }

                    List <Tuple <string, JObject> > edgeObjects;
                    if (!vertexIdAndEdgeObjectsDict.TryGetValue(vertexId, out edgeObjects))
                    {
                        edgeObjects = new List <Tuple <string, JObject> >();
                        vertexIdAndEdgeObjectsDict.Add(vertexId, edgeObjects);
                    }
                    edgeObjects.Add(new Tuple <string, JObject>((string)tmpObject[DocumentDBKeywords.KW_DOC_ID], edgeObject));

                    List <string> edgeIds;
                    if (!vertexIdAndEdgeIdsDict.TryGetValue(vertexId, out edgeIds))
                    {
                        edgeIds = new List <string>();
                        vertexIdAndEdgeIdsDict.Add(vertexId, edgeIds);
                    }
                    edgeIds.Add((string)edgeObject[DocumentDBKeywords.KW_DOC_ID]);
                }
                else
                {
                    string vertexId = (string)tmpObject[DocumentDBKeywords.KW_DOC_ID];
                    command.VertexCache.AddOrUpdateVertexField(vertexId, tmpObject);
                    List <string> edgeIds;
                    if (!vertexIdAndEdgeIdsDict.TryGetValue(vertexId, out edgeIds))
                    {
                        edgeIds = new List <string>();
                        vertexIdAndEdgeIdsDict.Add(vertexId, edgeIds);
                    }
                    edgeIds.Add((string)edgeObject[DocumentDBKeywords.KW_DOC_ID]);
                }
            }

            if (spilledVertexIdSet.Any())
            {
                const string NODE_ALISE = "Node";
                JsonQuery    query      = new JsonQuery
                {
                    NodeAlias = NODE_ALISE
                };
                query.AddSelectElement("*");
                query.RawWhereClause = new WInPredicate(new WColumnReferenceExpression(NODE_ALISE, "id"), spilledVertexIdSet.ToList());
                if (spilledVertexPartitionSet.Any())
                {
                    query.WhereConjunction(
                        new WInPredicate(
                            new WValueExpression($"{NODE_ALISE}{this.Connection.GetPartitionPathIndexer()}"),
                            spilledVertexPartitionSet.ToList()), BooleanBinaryExpressionType.And);
                }

                // TODO: remove this code when you understand it.
                //                string idInClause = string.Join(", ", spilledVertexIdSet.Select(id => $"'{id}'"));
                //                string partitionInClause = string.Join(", ", spilledVertexPartitionSet.Select(partition => $"'{partition}'"));
                //                string queryScript = $"SELECT * FROM Node WHERE Node.id IN ({idInClause})" +
                //                                     (string.IsNullOrEmpty(partitionInClause)
                //                                         ? ""
                //                                         : $" AND Node{this.Connection.GetPartitionPathIndexer()} IN ({partitionInClause})");
                //                IEnumerable<dynamic> spilledVertices = this.Connection.ExecuteDocDbQuery(queryScript);
                IEnumerable <JObject> spilledVertices = this.ExecuteQueryScript(query);
                foreach (JObject vertex in spilledVertices)
                {
                    JObject     vertexObject = vertex;
                    string      vertexId     = (string)vertexObject[DocumentDBKeywords.KW_DOC_ID];
                    VertexField vertexField  = command.VertexCache.AddOrUpdateVertexField(vertexId, vertexObject);
                    vertexField.ConstructPartialLazyAdjacencyList(vertexIdAndEdgeObjectsDict[vertexId], false);
                }
            }

            foreach (KeyValuePair <string, List <string> > pair in vertexIdAndEdgeIdsDict)
            {
                string        vertexId    = pair.Key;
                List <string> edgeIds     = pair.Value;
                VertexField   vertexField = command.VertexCache.GetVertexField(vertexId);

                foreach (string edgeId in edgeIds)
                {
                    RawRecord nodeRecord = new RawRecord();
                    //
                    // Fill node property field
                    //
                    foreach (string propertyName in nodeProperties)
                    {
                        FieldObject propertyValue = vertexField[propertyName];
                        nodeRecord.Append(propertyValue);
                    }

                    RawRecord edgeRecord = new RawRecord(edgeProperties.Count);

                    EdgeField edgeField = vertexField.AdjacencyList.GetEdgeField(edgeId, false);
                    Debug.Assert(edgeField != null, "edgeField != null");

                    string startVertexId = vertexField.VertexId;
                    AdjacencyListDecoder.FillMetaField(edgeRecord, edgeField, startVertexId, vertexField.Partition, true, false);
                    AdjacencyListDecoder.FillPropertyField(edgeRecord, edgeField, edgeProperties);

                    nodeRecord.Append(edgeRecord);
                    yield return(nodeRecord);
                }
            }
        }
Example #27
0
        internal override List <RawRecord> CrossApply(RawRecord record)
        {
            var results = new List <RawRecord>();

            // Extract all properties if allPropertyIndex >= 0
            if (allPropertyIndex >= 0 && record[allPropertyIndex] != null)
            {
                VertexField vertexField = record[allPropertyIndex] as VertexField;
                if (vertexField != null)
                {
                    foreach (PropertyField property in vertexField.AllProperties)
                    {
                        string propertyName = property.PropertyName;

                        switch (propertyName)
                        {
                        // Reversed properties for meta-data
                        case "_edge":
                        case "_partition":
                        case "_reverse_edge":
                        case "_nextEdgeOffset":

                        case "_rid":
                        case "_self":
                        case "_etag":
                        case "_attachments":
                        case "_ts":
                            continue;

                        default:
                            RawRecord r = new RawRecord();
                            if (property is VertexSinglePropertyField || property is ValuePropertyField)
                            {
                                r.Append(property);
                            }
                            else if (property is VertexPropertyField)
                            {
                                foreach (VertexSinglePropertyField p in ((VertexPropertyField)property).Multiples.Values)
                                {
                                    r.Append(p);
                                }
                            }
                            else
                            {
                                Debug.Assert(false, $"[PropertiesOperator.CrossApply] property type error: {property.GetType()}");
                            }

                            results.Add(r);
                            break;
                        }
                    }
                }
                else
                {
                    EdgeField edgeField = record[allPropertyIndex] as EdgeField;
                    if (edgeField == null)
                    {
                        throw new GraphViewException(
                                  string.Format("The FieldObject record[{0}] should be a VertexField or EdgeField but now it is {1}.",
                                                allPropertyIndex, record[allPropertyIndex].ToString()));
                    }

                    foreach (var propertyPair in edgeField.EdgeProperties)
                    {
                        string            propertyName  = propertyPair.Key;
                        EdgePropertyField propertyField = propertyPair.Value;

                        switch (propertyName)
                        {
                        // Reversed properties for meta-data
                        case "_offset":
                        case "_srcV":
                        case "_sinkV":
                        case "_srcVLabel":
                        case "_sinkVLabel":
                            continue;

                        default:
                            RawRecord r = new RawRecord();
                            r.Append(propertyField);
                            results.Add(r);
                            break;
                        }
                    }
                }
            }
            else
            {
                // TODO: Now translation code needn't to generate the key name for the operator
                foreach (var pair in propertyList)
                {
                    //string propertyName = pair.Item1;
                    int propertyValueIndex = pair.Item2;
                    var propertyValue      = record[propertyValueIndex];
                    if (propertyValue == null)
                    {
                        continue;
                    }

                    var result = new RawRecord();
                    result.Append(propertyValue);
                    results.Add(result);
                }
            }

            return(results);
        }
Example #28
0
        internal override List <RawRecord> CrossApply(RawRecord record)
        {
            var results = new List <RawRecord>();

            // Extract all values if allValuesIndex >= 0
            if (allValuesIndex >= 0 && record[allValuesIndex] != null)
            {
                VertexField vertexField = record[allValuesIndex] as VertexField;
                if (vertexField != null)
                {
                    foreach (PropertyField property in vertexField.AllProperties)
                    {
                        string propertyName = property.PropertyName;

                        switch (propertyName)
                        {
                        // Reversed properties for meta-data
                        case "_edge":
                        case "_reverse_edge":
                        case "_partition":
                        case "_nextEdgeOffset":

                        case "_rid":
                        case "_self":
                        case "_etag":
                        case "_attachments":
                        case "_ts":
                            continue;

                        default:
                            RawRecord r = new RawRecord();
                            r.Append(new StringField(property.PropertyValue, property.JsonDataType));
                            results.Add(r);
                            break;
                        }
                    }
                }
                else
                {
                    EdgeField edgeField = record[allValuesIndex] as EdgeField;
                    if (edgeField == null)
                    {
                        throw new GraphViewException(
                                  string.Format("The FieldObject record[{0}] should be a VertexField or EdgeField but now it is {1}.",
                                                allValuesIndex, record[allValuesIndex].ToString()));
                    }

                    foreach (var propertyPair in edgeField.EdgeProperties)
                    {
                        string            propertyName  = propertyPair.Key;
                        EdgePropertyField propertyField = propertyPair.Value;

                        switch (propertyName)
                        {
                        // Reversed properties for meta-data
                        case "_offset":
                        case "_srcV":
                        case "_srcVLabel":
                        case "_sinkV":
                        case "_sinkVLabel":
                            continue;

                        default:
                            RawRecord r = new RawRecord();
                            r.Append(new StringField(propertyField.ToValue, propertyField.JsonDataType));
                            results.Add(r);
                            break;
                        }
                    }
                }
            }
            else
            {
                foreach (var propIdx in ValuesIdxList)
                {
                    PropertyField propertyValue = record[propIdx] as PropertyField;
                    if (propertyValue == null)
                    {
                        continue;
                    }

                    var result = new RawRecord();
                    result.Append(new StringField(propertyValue.ToValue, propertyValue.JsonDataType));
                    results.Add(result);
                }
            }

            return(results);
        }
Example #29
0
        internal override List <RawRecord> CrossApply(RawRecord record)
        {
            List <RawRecord> results = new List <RawRecord>();

            FieldObject inputTarget = record[this.inputTargetIndex];

            if (inputTarget is VertexField)
            {
                VertexField vertexField = (VertexField)inputTarget;
                foreach (VertexPropertyField property in vertexField.VertexProperties.Values)
                {
                    string propertyName = property.PropertyName;
                    Debug.Assert(!VertexField.IsVertexMetaProperty(propertyName));
                    Debug.Assert(propertyName == "_edge");
                    Debug.Assert(propertyName == "_reverse_edge");

                    switch (propertyName)
                    {
                    case "_rid":
                    case "_self":
                    case "_etag":
                    case "_attachments":
                    case "_ts":
                        continue;

                    default:
                        foreach (VertexSinglePropertyField singleVp in property.Multiples.Values)
                        {
                            RawRecord r = new RawRecord();
                            r.Append(new StringField(singleVp.PropertyValue, singleVp.JsonDataType));
                            results.Add(r);
                        }
                        break;
                    }
                }
            }
            else if (inputTarget is EdgeField)
            {
                EdgeField edgeField = (EdgeField)inputTarget;

                foreach (KeyValuePair <string, EdgePropertyField> propertyPair in edgeField.EdgeProperties)
                {
                    string            propertyName      = propertyPair.Key;
                    EdgePropertyField edgePropertyField = propertyPair.Value;

                    switch (propertyName)
                    {
                    // Reserved properties for meta-data
                    case "_edgeId":
                    case "_offset":
                    case "_srcV":
                    case "_sinkV":
                    case "_srcVLabel":
                    case "_sinkVLabel":
                        continue;

                    default:
                        RawRecord r = new RawRecord();
                        r.Append(new StringField(edgePropertyField.PropertyValue, edgePropertyField.JsonDataType));
                        results.Add(r);
                        break;
                    }
                }
            }
            else if (inputTarget is VertexSinglePropertyField)
            {
                VertexSinglePropertyField singleVp = inputTarget as VertexSinglePropertyField;
                foreach (KeyValuePair <string, ValuePropertyField> kvp in singleVp.MetaProperties)
                {
                    RawRecord          r = new RawRecord();
                    ValuePropertyField metaPropertyField = kvp.Value;
                    r.Append(new StringField(metaPropertyField.PropertyValue, metaPropertyField.JsonDataType));
                    results.Add(r);
                }
            }
            else
            {
                throw new GraphViewException("The input of values() cannot be a meta or edge property.");
            }
            return(results);
        }
        internal override RawRecord DataModify(RawRecord record)
        {
            long   edgeOffset  = long.Parse(record[this._edgeOffsetIndex].ToValue);
            string srcVertexId = record[this._srcVertexIdIndex].ToValue;

            JObject srcVertexObject = this.Connection.RetrieveDocumentById(srcVertexId);
            string  outEdgeDocId;
            JObject outEdgeObject;

            EdgeDocumentHelper.FindEdgeBySourceAndOffset(
                this.Connection, srcVertexObject, srcVertexId, edgeOffset, false,
                out outEdgeObject, out outEdgeDocId);
            if (outEdgeObject == null)
            {
                // TODO: Is there something wrong?
                Debug.WriteLine($"[UpdateEdgePropertiesOperator] The edge does not exist: vertexId = {srcVertexId}, edgeOffset = {edgeOffset}");
                return(null);
            }

            string  sinkVertexId = (string)outEdgeObject["_sinkV"];
            JObject sinkVertexObject;
            string  inEdgeDocId;
            JObject inEdgeObject;

            if (sinkVertexId.Equals(srcVertexId))
            {
                sinkVertexObject = srcVertexObject;  // NOTE: Must not use DeepClone() here!
            }
            else
            {
                sinkVertexObject = this.Connection.RetrieveDocumentById(sinkVertexId);
            }
            EdgeDocumentHelper.FindEdgeBySourceAndOffset(
                this.Connection, sinkVertexObject, srcVertexId, edgeOffset, true,
                out inEdgeObject, out inEdgeDocId);

            VertexField srcVertexField  = this.Connection.VertexCache.GetVertexField(srcVertexId);
            VertexField sinkVertexField = this.Connection.VertexCache.GetVertexField(sinkVertexId);
            EdgeField   outEdgeField    = srcVertexField.AdjacencyList.GetEdgeField(srcVertexId, edgeOffset);
            EdgeField   inEdgeField     = sinkVertexField.RevAdjacencyList.GetEdgeField(srcVertexId, edgeOffset);

            // Drop all non-reserved properties
            if (this.PropertiesToBeUpdated.Count == 1 &&
                !this.PropertiesToBeUpdated[0].Item1.SingleQuoted &&
                this.PropertiesToBeUpdated[0].Item1.Value.Equals("*", StringComparison.OrdinalIgnoreCase) &&
                !this.PropertiesToBeUpdated[0].Item2.SingleQuoted &&
                this.PropertiesToBeUpdated[0].Item2.Value.Equals("null", StringComparison.OrdinalIgnoreCase))
            {
                List <string> toBeDroppedProperties = GraphViewJsonCommand.DropAllEdgeProperties(outEdgeObject);
                foreach (var propertyName in toBeDroppedProperties)
                {
                    outEdgeField.EdgeProperties.Remove(propertyName);
                }

                toBeDroppedProperties = GraphViewJsonCommand.DropAllEdgeProperties(inEdgeObject);
                foreach (var propertyName in toBeDroppedProperties)
                {
                    inEdgeField.EdgeProperties.Remove(propertyName);
                }
            }
            else
            {
                foreach (Tuple <WValueExpression, WValueExpression, int> tuple in this.PropertiesToBeUpdated)
                {
                    WValueExpression keyExpression   = tuple.Item1;
                    WValueExpression valueExpression = tuple.Item2;

                    if (this.Mode == UpdatePropertyMode.Set)
                    {
                        // Modify edgeObject (update the edge property)
                        JProperty updatedProperty = GraphViewJsonCommand.UpdateProperty(outEdgeObject, keyExpression, valueExpression);
                        // Update VertexCache
                        if (updatedProperty == null)
                        {
                            outEdgeField.EdgeProperties.Remove(keyExpression.Value);
                        }
                        else
                        {
                            outEdgeField.UpdateEdgeProperty(updatedProperty, outEdgeField);
                        }

                        // Modify edgeObject (update the edge property)
                        updatedProperty = GraphViewJsonCommand.UpdateProperty(inEdgeObject, keyExpression, valueExpression);
                        // Update VertexCache
                        if (updatedProperty == null)
                        {
                            inEdgeField.EdgeProperties.Remove(keyExpression.Value);
                        }
                        else
                        {
                            inEdgeField.UpdateEdgeProperty(updatedProperty, inEdgeField);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }

            // Interact with DocDB to update the property
            EdgeDocumentHelper.UpdateEdgeProperty(this.Connection, srcVertexObject, outEdgeDocId, false, outEdgeObject);
            EdgeDocumentHelper.UpdateEdgeProperty(this.Connection, sinkVertexObject, inEdgeDocId, true, inEdgeObject);


            //
            // Drop edge property
            //
            if (this.PropertiesToBeUpdated.Any(t => t.Item2 == null))
            {
                return(null);
            }
            return(record);
        }