Ejemplo n.º 1
0
 public GraphViewCommand(string commandText, GraphViewConnection connection, SqlTransaction transaction)
 {
     CommandText = commandText;
     GraphViewConnection = connection;
     Command = GraphViewConnection.Conn.CreateCommand();
     Tx = transaction;
 }
Ejemplo n.º 2
0
        public int ExecuteNonQuery()
        {
            try
            {
                if (CommandType == CommandType.StoredProcedure)
                {
                    if (Tx != null)
                    {
                        Command.Transaction = Tx;
                    }
                    Command.CommandText = CommandText;
                    return(Command.ExecuteNonQuery());
                }

                var sr     = new StringReader(CommandText);
                var parser = new GraphViewParser();
                IList <ParseError> errors;
                var script = parser.Parse(sr, out errors) as WSqlScript;
                if (errors.Count > 0)
                {
                    throw new SyntaxErrorException(errors);
                }

                bool externalTransaction = true;
                if (Tx == null)
                {
                    externalTransaction = false;
                    Tx = GraphViewConnection.BeginTransaction();
                }

                // Translation
                var modVisitor = new TranslateDataModificationVisitor(Tx);
                modVisitor.Invoke(script);
                var matchVisitor = new TranslateMatchClauseVisitor(Tx);
                matchVisitor.Invoke(script);

                Command.CommandText = script.ToString();
                Command.Transaction = Tx;
#if DEBUG
                // For debugging
                OutputResult(CommandText, Command.CommandText);
#endif
                int res = Command.ExecuteNonQuery();
                if (!externalTransaction)
                {
                    Tx.Commit();
                    Tx.Dispose();
                    Tx = null;
                }
                return(res);
            }
            catch (SqlException e)
            {
                throw new SqlExecutionException("An error occurred when executing the query", e);
            }
        }
Ejemplo n.º 3
0
        public static void run()
        {
            GraphViewConnection con = new GraphViewConnection(TutorialConfiguration.getConnectionString());
            con.Open();
            con.ClearData();
            try
            {
                generateFiles();

                Console.WriteLine("Creating tables...");
                #region Create a schema for reader and book
                con.CreateNodeTable(@"CREATE TABLE [Book] ( 
                    [ColumnRole:""NodeId""] name VARCHAR(40) )");

                con.CreateNodeTable(@"CREATE TABLE [Reader] ( 
                    [ColumnRole:""NodeId""] name VARCHAR(30),
                    [ColumnRole:""Property""] gender VARCHAR(10),
                    [ColumnRole:""Edge"",Reference:""Book""] Reads VARBINARY(max) )");
                #endregion

                Console.WriteLine("BulkLoading...");
                #region Bulk Load Nodes
                con.BulkInsertNode(ReaderFileName, "Reader", "dbo", null, ",", "\n");
                con.BulkInsertNode(BookFileName, "Book", "dbo", null, ",", "\n");
                con.BulkInsertEdge(readRelationFileName, "dbo", "Reader", "name", "Book", "name", "Reads", null, ",", "\n");
                #endregion

                Console.WriteLine("Querying...");
                #region Query
                var res = con.ExecuteReader(@"SELECT x.name as name1, y.name as name2 FROM Reader x, Book y
                                MATCH x-[Reads]->y ");
                try
                {
                    while (res.Read())
                    {
                        System.Console.WriteLine(res["name1"].ToString() + " Reads " + res["name2"].ToString());
                    }
                }
                finally
                {
                    if (res != null)
                        res.Close();
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }
            finally //  close the connection and drop table
            {
                con.ClearGraphDatabase();
                con.Close();
                deleteFiles();
            }
        }
 public UpdatePropertiesOperator(
     GraphViewExecutionOperator dummyInputOp,
     GraphViewConnection connection,
     int updateTargetIndex,
     List <WPropertyExpression> updateProperties)
     : base(dummyInputOp, connection)
 {
     this.updateTargetIndex = updateTargetIndex;
     this.updateProperties  = updateProperties;
 }
 public UpdateEdgePropertiesOperator(
     GraphViewExecutionOperator inputOp, GraphViewConnection connection,
     int srcVertexIdIndex, int edgeOffsetIndex,
     List <Tuple <WValueExpression, WValueExpression, int> > propertiesList,
     UpdatePropertyMode pMode = UpdatePropertyMode.Set)
     : base(inputOp, connection, propertiesList, pMode)
 {
     this._srcVertexIdIndex = srcVertexIdIndex;
     this._edgeOffsetIndex  = edgeOffsetIndex;
 }
 public AddEOperator(GraphViewExecutionOperator inputOp, GraphViewConnection connection,
                     ScalarFunction pSrcFunction, ScalarFunction pSinkFunction,
                     int otherVTag, JObject pEdgeJsonObject, List <string> pProjectedFieldList)
     : base(inputOp, connection)
 {
     _srcFunction    = pSrcFunction;
     _sinkFunction   = pSinkFunction;
     _otherVTag      = otherVTag;
     _edgeJsonObject = pEdgeJsonObject;
     _edgeProperties = pProjectedFieldList;
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Try to upload one document.
 /// If the operation fails because document is too large, nothing is changed and "tooLarge" is set true.
 /// If the operation fails due to other reasons, nothing is changed and an exception is thrown
 /// If the operation succeeds, docObject["id"] is set if it doesn't have one
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="docId"></param>
 /// <param name="docObject"></param>
 /// <param name="tooLarge"></param>
 private static void UploadOne(GraphViewConnection connection, string docId, JObject docObject, out bool tooLarge)
 {
     tooLarge = false;
     try {
         connection.ReplaceOrDeleteDocumentAsync(docId, docObject).Wait();
     }
     catch (AggregateException ex) when(ex.InnerException?.GetType().Name.Equals("RequestEntityTooLargeException") ?? false)
     {
         tooLarge = true;
     }
 }
Ejemplo n.º 8
0
        public BulkOperationAddVertex(GraphViewConnection connection, JObject vertexObject)
            : base(connection, "AddVertex")
        {
            this._vertexObject = vertexObject;

            // OperationJObject
            this.OperationJObject["vertexObject"] = vertexObject;

            // KnownEtags:
            // Does need add anything
        }
Ejemplo n.º 9
0
        internal static void GetPathStepListAndByFuncList(
            QueryCompilationContext context, GraphViewConnection dbConnection,
            IList <WScalarExpression> parameters,
            out List <Tuple <ScalarFunction, bool, HashSet <string> > > pathStepList,
            out List <ScalarFunction> byFuncList)
        {
            //
            // If the boolean value is true, then it's a subPath to be unfolded
            //
            pathStepList = new List <Tuple <ScalarFunction, bool, HashSet <string> > >();
            byFuncList   = new List <ScalarFunction>();
            QueryCompilationContext byInitContext = new QueryCompilationContext(context);

            byInitContext.ClearField();
            byInitContext.AddField(GremlinKeyword.Compose1TableDefaultName, GremlinKeyword.TableDefaultColumnName, ColumnGraphType.Value);

            foreach (WScalarExpression expression in parameters)
            {
                WFunctionCall              basicStep = expression as WFunctionCall;
                WValueExpression           stepLabel = expression as WValueExpression;
                WColumnReferenceExpression subPath   = expression as WColumnReferenceExpression;
                WScalarSubquery            byFunc    = expression as WScalarSubquery;

                if (basicStep != null)
                {
                    pathStepList.Add(
                        new Tuple <ScalarFunction, bool, HashSet <string> >(
                            basicStep.CompileToFunction(context, dbConnection), false, new HashSet <string>()));
                }
                else if (stepLabel != null)
                {
                    if (!pathStepList.Any())
                    {
                        pathStepList.Add(new Tuple <ScalarFunction, bool, HashSet <string> >(null, false, new HashSet <string>()));
                    }
                    pathStepList.Last().Item3.Add(stepLabel.Value);
                }
                else if (subPath != null)
                {
                    pathStepList.Add(
                        new Tuple <ScalarFunction, bool, HashSet <string> >(
                            subPath.CompileToFunction(context, dbConnection), true, new HashSet <string>()));
                }
                else if (byFunc != null)
                {
                    byFuncList.Add(byFunc.CompileToFunction(byInitContext, dbConnection));
                }
                else
                {
                    throw new QueryCompilationException(
                              "The parameter of WPathTableReference can only be a WFunctionCall/WValueExpression/WColumnReferenceExpression/WScalarSubquery.");
                }
            }
        }
Ejemplo n.º 10
0
        public JObject ConstructNodeJsonDocument(string vertexLabel, List <WPropertyExpression> vertexProperties, out List <string> projectedFieldList)
        {
            Debug.Assert(vertexLabel != null);
            JObject vertexObject = new JObject {
                ["label"] = vertexLabel
            };

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

            foreach (WPropertyExpression vertexProperty in vertexProperties)
            {
                Debug.Assert(vertexProperty.Cardinality == GremlinKeyword.PropertyCardinality.list);

                if (!projectedFieldList.Contains(vertexProperty.Key.Value))
                {
                    projectedFieldList.Add(vertexProperty.Key.Value);
                }

                if (vertexProperty.Value.ToJValue() == null)
                {
                    continue;
                }

                JObject meta = new JObject();
                foreach (KeyValuePair <WValueExpression, WValueExpression> pair in vertexProperty.MetaProperties)
                {
                    WValueExpression metaName  = pair.Key;
                    WValueExpression metaValue = pair.Value;
                    meta[metaName.Value] = metaValue.ToJValue();
                }

                string name      = vertexProperty.Key.Value;
                JArray propArray = (JArray)vertexObject[name];
                if (propArray == null)
                {
                    propArray          = new JArray();
                    vertexObject[name] = propArray;
                }

                propArray.Add(new JObject {
                    ["_value"]  = vertexProperty.Value.ToJValue(),
                    ["_propId"] = GraphViewConnection.GenerateDocumentId(),
                    ["_meta"]   = meta,
                });
                //GraphViewJsonCommand.AppendVertexSinglePropertyToVertex(vertexObject);
            }

            vertexObject["_edge"]           = new JArray();
            vertexObject["_reverse_edge"]   = new JArray();
            vertexObject["_nextEdgeOffset"] = 0;

            return(vertexObject);
        }
Ejemplo n.º 11
0
        public JObject ConstructNodeJsonDocument(string vertexLabel, List <WPropertyExpression> vertexProperties)
        {
            Debug.Assert(vertexLabel != null);
            JObject vertexObject = new JObject {
                [KW_VERTEX_LABEL] = vertexLabel
            };

            //projectedFieldList = new List<string>(GraphViewReservedProperties.InitialPopulateNodeProperties);
            //projectedFieldList.Add(GremlinKeyword.Label);

            foreach (WPropertyExpression vertexProperty in vertexProperties)
            {
                Debug.Assert(vertexProperty.Cardinality == GremlinKeyword.PropertyCardinality.List);

                //if (!projectedFieldList.Contains(vertexProperty.Key.Value))
                //    projectedFieldList.Add(vertexProperty.Key.Value);

                //if (vertexProperty.Value.ToJValue() == null) {
                //    continue;
                //}

                JObject meta = new JObject();
                foreach (KeyValuePair <WValueExpression, WValueExpression> pair in vertexProperty.MetaProperties)
                {
                    WValueExpression metaName  = pair.Key;
                    WValueExpression metaValue = pair.Value;
                    meta[metaName.Value] = metaValue.ToJValue();
                }

                string name      = vertexProperty.Key.Value;
                JArray propArray = (JArray)vertexObject[name];
                if (propArray == null)
                {
                    propArray          = new JArray();
                    vertexObject[name] = propArray;
                }

                propArray.Add(new JObject {
                    [KW_PROPERTY_VALUE] = vertexProperty.Value.ToJValue(),
                    [KW_PROPERTY_ID]    = GraphViewConnection.GenerateDocumentId(),
                    [KW_PROPERTY_META]  = meta,
                });
                //GraphViewJsonCommand.AppendVertexSinglePropertyToVertex(vertexObject);
            }

            vertexObject[KW_VERTEX_EDGE]            = new JArray();
            vertexObject[KW_VERTEX_REV_EDGE]        = new JArray();
            vertexObject[KW_VERTEX_EDGE_SPILLED]    = false;
            vertexObject[KW_VERTEX_REVEDGE_SPILLED] = false;
            //vertexObject[KW_VERTEX_NEXTOFFSET] = 0;

            return(vertexObject);
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Try to upload one document.
 /// If the operation fails because document is too large, nothing is changed and "tooLarge" is set true.
 /// If the operation fails due to other reasons, nothing is changed and an exception is thrown
 /// If the operation succeeds, docObject["id"] is set if it doesn't have one
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="docId"></param>
 /// <param name="docObject"></param>
 /// <param name="tooLarge"></param>
 private static void UploadOne(GraphViewConnection connection, string docId, JObject docObject, out bool tooLarge)
 {
     tooLarge = false;
     try {
         Debug.Assert(docObject != null);
         connection.ReplaceOrDeleteDocumentAsync(docId, docObject, (string)docObject["_partition"]).Wait();
     }
     catch (AggregateException ex)
         when((ex.InnerException as DocumentClientException)?.Error.Code == "RequestEntityTooLarge")
         {
             tooLarge = true;
         }
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Construct a VertexCache from a connection.
        /// NOTE: VertexCache is per-collection, but for the same colloction, it's cross-connection
        /// </summary>
        /// <param name="connection"></param>
        /// <returns></returns>
        public static VertexObjectCache FromConnection(GraphViewConnection connection)
        {
            Debug.Assert(connection.Identifier != null, "The connection's identifier must have been initialized");

            // MUST NOT use __caches.GetOrAdd() here!
            var cachedVertexField = new Dictionary <string, VertexField>();

            if (!__caches.TryAdd(connection.Identifier, cachedVertexField))
            {
                cachedVertexField = __caches[connection.Identifier];
            }

            return(new VertexObjectCache(connection, cachedVertexField));
        }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Find incoming or outgoing edge by "srcId and edgeId"
        /// Output the edgeObject, as well as the edgeDocId (null for small-degree edges)
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="vertexObject"></param>
        /// <param name="srcVertexId"></param>
        /// <param name="edgeId"></param>
        /// <param name="isReverseEdge"></param>
        /// <param name="edgeObject"></param>
        /// <param name="edgeDocId"></param>
        public static void FindEdgeBySourceAndEdgeId(
            GraphViewConnection connection,
            JObject vertexObject, string srcVertexId, string edgeId, bool isReverseEdge,
            out JObject edgeObject, out string edgeDocId)
        {
            if (!isReverseEdge)
            {
                Debug.Assert((string)vertexObject[KW_DOC_ID] == srcVertexId);
            }
            JToken edgeContainer = vertexObject[isReverseEdge ? KW_VERTEX_REV_EDGE : KW_VERTEX_EDGE];

            if (!IsSpilledVertex(vertexObject, isReverseEdge))
            {
                // for small-degree vertexes
                if (isReverseEdge)
                {
                    edgeObject = (from edgeObj in edgeContainer.Children <JObject>()
                                  where (string)edgeObj[KW_EDGE_SRCV] == srcVertexId
                                  where (string)edgeObj[KW_EDGE_ID] == edgeId
                                  select edgeObj
                                  ).FirstOrDefault();
                }
                else
                {
                    edgeObject = (from edgeObj in edgeContainer.Children <JObject>()
                                  where (string)edgeObj[KW_EDGE_ID] == edgeId
                                  select edgeObj
                                  ).FirstOrDefault();
                }
                edgeDocId = null;
            }
            else    // For large-degree vertices
            // Now the vertex document stores the last(latest) spilled edge document only.
            //string edgeDocIdList = string.Join(", ", edgeContainer.Children<JObject>().Select(e => $"'{e[KW_DOC_ID]}'"));

            {
                const string EDGE_SELECT_TAG = "edge";
                string       query           = $"SELECT doc.{KW_DOC_ID}, {EDGE_SELECT_TAG}\n" +
                                               $"FROM doc\n" +
                                               $"JOIN {EDGE_SELECT_TAG} IN doc.{KW_EDGEDOC_EDGE}\n" +
                                               $"WHERE (doc.{KW_EDGEDOC_ISREVERSE} = {isReverseEdge.ToString().ToLowerInvariant()})\n" +
                                               $"  AND ({EDGE_SELECT_TAG}.{KW_EDGE_ID} = '{edgeId}')\n";

                JObject result = connection.ExecuteQueryUnique(query);
                edgeDocId  = (string)result?[KW_DOC_ID];
                edgeObject = (JObject)result?[EDGE_SELECT_TAG];
            }
        }
Ejemplo n.º 16
0
        }                                                                              // Can be null



        public BulkOperationUpdateEdgeProperty(
            GraphViewConnection connection,
            string srcOrSinkVertexId, string edgeId, string edgeDocId,
            bool isReverse, int?spillThreshold, JObject updateProperties)
            : base(connection, "UpdateEdgeProperty")
        {
            /* Parameter schema:
             *  {
             *      "op": "UpdateEdgeProperty",
             *      "srcOrSinkVertexId": ...,
             *      "edgeId": ...,
             *      "edgeDocId": ...,
             *      "isReverse": true/false,
             *      "spillThreshold": null/0/>0,
             *      "updateProperties": {
             *          "prop1": "v1",
             *          "prop2": "v2",
             *          ...
             *      }
             *  }
             * Response content:
             *  {
             *      "found": true/false
             *
             *      // If the edge is originally spilled
             *      "newEdgeDocId": ...,    // To which edge-document is this edge stored (Can't be null if spilled)
             *                              // NOTE: If this edge is spilled to a new new edge-document, it must be the vertex's latest edge-document
             *
             *      // Or... if the edge is originally not spilled
             *      "didSpill": true/false
             *      "vertexFirstEdgeDocId": ...,  // Can be null
             *      "vertexLatestEdgeDocId": ...,  // Can be null                }
             */

            this.OperationJObject["srcOrSinkVertexId"] = srcOrSinkVertexId;
            this.OperationJObject["edgeId"]            = edgeId;
            this.OperationJObject["edgeDocId"]         = edgeDocId;
            this.OperationJObject["isReverse"]         = isReverse;
            this.OperationJObject["spillThreshold"]    = spillThreshold;
            this.OperationJObject["updateProperties"]  = updateProperties;

            this.KnownEtags[srcOrSinkVertexId] = connection.VertexCache.GetCurrentEtag(srcOrSinkVertexId);
            if (edgeDocId != null)
            {
                this.KnownEtags[edgeDocId] = connection.VertexCache.TryGetCurrentEtag(edgeDocId);
            }
        }
Ejemplo n.º 17
0
        public BulkOperationDropVertexProperty(GraphViewConnection connection, string vertexId, string propertyName)
            : base(connection, "DropVertexProperty")
        {
            /* Parameter schema:
             *  {
             *      "op": "DropVertexProperty",
             *      "vertexId": ...,
             *      "propertyName": ...,
             *  }
             * Response content:
             *  {
             *      "found": true/false
             *  }
             */

            this.OperationJObject["vertexId"]     = vertexId;
            this.OperationJObject["propertyName"] = propertyName;

            this.KnownEtags[vertexId] = connection.VertexCache.GetCurrentEtag(vertexId);  // Not null
        }
Ejemplo n.º 18
0
        private static Dictionary <string, string> GetLabelOfSrcVertexOfSpilledEdges(
            GraphViewConnection connection, List <dynamic> virtualReverseEdges)
        {
            Dictionary <string, string> labelOfVertexCollection = new Dictionary <string, string>();
            HashSet <string>            vertexIdSet             = new HashSet <string>();

            foreach (JObject virtualReverseEdge in virtualReverseEdges)
            {
                JObject virtualReverseEdgeObject = (JObject)virtualReverseEdge[EdgeDocumentHelper.VirtualReverseEdge];
                string  vertexId = virtualReverseEdgeObject[KW_EDGEDOC_VERTEXID]?.ToString();
                if (vertexId != null)
                {
                    //
                    // this is a spilled edge, so the srcVLabel is not in the spilled document and needs to be fetched
                    //
                    vertexIdSet.Add(vertexId);
                }
            }

            if (vertexIdSet.Any())
            {
                string inClause   = string.Join(", ", vertexIdSet.Select(vertexId => $"'{vertexId}'"));
                string labelQuery =
                    $"SELECT doc.{KW_VERTEX_LABEL}, doc.{KW_DOC_ID} " +
                    $"FROM doc " +
                    $"WHERE doc.{KW_DOC_ID} IN ({inClause})";
                IQueryable <dynamic> vertexIdAndLabels = connection.ExecuteQuery(labelQuery);
                foreach (JObject vertexIdAndLabel in vertexIdAndLabels)
                {
                    string vertexId    = vertexIdAndLabel[KW_DOC_ID].ToString();
                    string vertexLabel = vertexIdAndLabel[KW_VERTEX_LABEL]?.ToString();
                    labelOfVertexCollection[vertexId] = vertexLabel;
                }
            }

            return(labelOfVertexCollection);
        }
Ejemplo n.º 19
0
        public BulkOperationDropEdgeProperty(
            GraphViewConnection connection,
            string srcOrSinkVertexId, string edgeId, string edgeDocId,
            bool isReverse, string[] dropProperties)
            : base(connection, "DropEdgeProperty")
        {
            /* Parameter schema:
             *  {
             *      "op": "DropEdgeProperty",
             *      "srcOrSinkVertexId": ...,
             *      "edgeId": ...,
             *      "edgeDocId": ...,
             *      "isReverse": true/false,
             *      "dropProperties": [
             *          "prop1", "prop2", "prop3", ...
             *      ]
             *  }
             * Response content:
             *  {
             *      "found": true/false
             *      "oppoSideVId": ...
             *  }
             */

            this.OperationJObject["srcOrSinkVertexId"] = srcOrSinkVertexId;
            this.OperationJObject["edgeId"]            = edgeId;
            this.OperationJObject["edgeDocId"]         = edgeDocId;
            this.OperationJObject["isReverse"]         = isReverse;
            this.OperationJObject["dropProperties"]    = new JArray(new HashSet <string>(dropProperties).Cast <object>().ToArray());


            this.KnownEtags[srcOrSinkVertexId] = connection.VertexCache.GetCurrentEtag(srcOrSinkVertexId);
            if (edgeDocId != null)
            {
                this.KnownEtags[edgeDocId] = connection.VertexCache.TryGetCurrentEtag(edgeDocId);
            }
        }
Ejemplo n.º 20
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;
            }
        }
Ejemplo n.º 21
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            //
            // Parameters:
            //   #1 <WValueExpression>: Vertex label
            //   ... <WPropertyExpression>: The initial properties on vertex
            //

            WValueExpression labelValue = (WValueExpression)this.Parameters[0];

            List <WPropertyExpression> vertexProperties = new List <WPropertyExpression>();

            for (int i = 1; i < this.Parameters.Count; i++)
            {
                WPropertyExpression property = (WPropertyExpression)this.Parameters[i];
                Debug.Assert(property != null, "[WAddVTableReference.Compile] Vertex property should not be null");
                Debug.Assert(property.Cardinality == GremlinKeyword.PropertyCardinality.list, "[WAddVTableReference.Compile] Vertex property should be append-mode");
                Debug.Assert(property.Value != null);

                vertexProperties.Add(property);
            }

            List <string> projectedField;

            JObject nodeJsonDocument = ConstructNodeJsonDocument(labelValue.Value, vertexProperties, out projectedField);

            AddVOperator addVOp = new AddVOperator(
                context.CurrentExecutionOperator,
                dbConnection,
                nodeJsonDocument,
                projectedField);

            context.CurrentExecutionOperator = addVOp;

            context.AddField(Alias.Value, "id", ColumnGraphType.VertexId);
            context.AddField(Alias.Value, "label", ColumnGraphType.Value);
            context.AddField(Alias.Value, "_edge", ColumnGraphType.OutAdjacencyList);
            context.AddField(Alias.Value, "_reverse_edge", ColumnGraphType.InAdjacencyList);
            context.AddField(Alias.Value, "*", ColumnGraphType.VertexObject);
            for (var i = GraphViewReservedProperties.ReservedNodeProperties.Count; i < projectedField.Count; i++)
            {
                context.AddField(Alias.Value, projectedField[i], ColumnGraphType.Value);
            }

            return(addVOp);
        }
Ejemplo n.º 22
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()}");
            }
        }
Ejemplo n.º 23
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            var srcIdParameter      = Parameters[0] as WColumnReferenceExpression;
            var edgeOffsetParameter = Parameters[1] as WColumnReferenceExpression;
            var srcIdIndex          = context.LocateColumnReference(srcIdParameter);
            var edgeOffsetIndex     = context.LocateColumnReference(edgeOffsetParameter);
            var edgeAlias           = edgeOffsetParameter.TableReference;
            var propertiesList      = new List <Tuple <WValueExpression, WValueExpression, int> >();

            for (var i = 2; i < Parameters.Count; i += 2)
            {
                var keyExpression   = Parameters[i] as WValueExpression;
                var valueExpression = Parameters[i + 1] as WValueExpression;

                int propertyIndex;
                if (!context.TryLocateColumnReference(new WColumnReferenceExpression(edgeAlias, keyExpression.Value), out propertyIndex))
                {
                    propertyIndex = -1;
                }

                propertiesList.Add(new Tuple <WValueExpression, WValueExpression, int>(keyExpression, valueExpression, propertyIndex));
            }

            var updateEdgePropertiesOp = new UpdateEdgePropertiesOperator(context.CurrentExecutionOperator, dbConnection,
                                                                          srcIdIndex, edgeOffsetIndex, propertiesList);

            context.CurrentExecutionOperator = updateEdgePropertiesOp;

            return(updateEdgePropertiesOp);
        }
Ejemplo n.º 24
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            WColumnReferenceExpression updateParameter = this.Parameters[0] as WColumnReferenceExpression;
            int updateIndex    = context.LocateColumnReference(updateParameter);
            var propertiesList = new List <WPropertyExpression>();

            for (int i = 1; i < this.Parameters.Count; ++i)
            {
                propertiesList.Add((WPropertyExpression)this.Parameters[i]);
#if DEBUG
                ((WPropertyExpression)this.Parameters[i]).Value.ToJValue();
#endif
            }

            UpdatePropertiesOperator updateOp = new UpdatePropertiesOperator(
                context.CurrentExecutionOperator,
                dbConnection,
                updateIndex,
                propertiesList);
            context.CurrentExecutionOperator = updateOp;

            return(updateOp);
        }
Ejemplo n.º 25
0
        internal GraphViewExecutionOperator Compile2(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            WColumnReferenceExpression dropTargetParameter = Parameters[0] as WColumnReferenceExpression;

            Debug.Assert(dropTargetParameter != null, "dropTargetParameter != null");
            int dropTargetIndex = context.LocateColumnReference(dropTargetParameter);

            //
            // A new DropOperator which drops target based on its runtime type
            //
            DropNodeOperator dropOp = new DropNodeOperator(context.CurrentExecutionOperator, dbConnection, dropTargetIndex);

            context.CurrentExecutionOperator = dropOp;

            return(dropOp);
        }
Ejemplo n.º 26
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            var srcIdParameter      = Parameters[0] as WColumnReferenceExpression;
            var edgeOffsetParameter = Parameters[1] as WColumnReferenceExpression;
            var srcIdIndex          = context.LocateColumnReference(srcIdParameter);
            var edgeOffsetIndex     = context.LocateColumnReference(edgeOffsetParameter);

            var dropEdgeOp = new DropEdgeOperator(context.CurrentExecutionOperator, dbConnection, srcIdIndex, edgeOffsetIndex);

            context.CurrentExecutionOperator = dropEdgeOp;

            return(dropEdgeOp);
        }
Ejemplo n.º 27
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            List <string> projectedField;
            var           edgeJsonObject = ConstructEdgeJsonObject(out projectedField); // metadata remains missing

            var srcSubQuery  = Parameters[0] as WScalarSubquery;
            var sinkSubQuery = Parameters[1] as WScalarSubquery;

            if (srcSubQuery == null || sinkSubQuery == null)
            {
                throw new SyntaxErrorException("The first two parameters of AddE can only be WScalarSubquery.");
            }
            var otherVTagParameter = Parameters[2] as WValueExpression;
            var otherVTag          = int.Parse(otherVTagParameter.Value);

            var srcSubQueryFunction  = srcSubQuery.CompileToFunction(context, dbConnection);
            var sinkSubQueryFunction = sinkSubQuery.CompileToFunction(context, dbConnection);

            GraphViewExecutionOperator addEOp = new AddEOperator(context.CurrentExecutionOperator,
                                                                 dbConnection, srcSubQueryFunction, sinkSubQueryFunction, otherVTag, edgeJsonObject, projectedField);

            context.CurrentExecutionOperator = addEOp;

            // Update context's record layout
            context.AddField(Alias.Value, "_source", ColumnGraphType.EdgeSource);
            context.AddField(Alias.Value, "_sink", ColumnGraphType.EdgeSink);
            context.AddField(Alias.Value, "_other", ColumnGraphType.Value);
            context.AddField(Alias.Value, "_offset", ColumnGraphType.EdgeOffset);
            context.AddField(Alias.Value, "*", ColumnGraphType.EdgeObject);
            for (var i = GraphViewReservedProperties.ReservedEdgeProperties.Count; i < projectedField.Count; i++)
            {
                context.AddField(Alias.Value, projectedField[i], ColumnGraphType.Value);
            }

            return(addEOp);
        }
Ejemplo n.º 28
0
        internal override GraphViewExecutionOperator Compile(QueryCompilationContext context, GraphViewConnection dbConnection)
        {
            List <string> projectedField;
            JObject       nodeJsonDocument = ConstructNodeJsonDocument(out projectedField);

            GraphViewExecutionOperator addVOp = new AddVOperator(context.CurrentExecutionOperator, dbConnection, nodeJsonDocument, projectedField);

            context.CurrentExecutionOperator = addVOp;

            context.AddField(Alias.Value, "id", ColumnGraphType.VertexId);
            context.AddField(Alias.Value, "label", ColumnGraphType.Value);
            context.AddField(Alias.Value, "_edge", ColumnGraphType.OutAdjacencyList);
            context.AddField(Alias.Value, "_reverse_edge", ColumnGraphType.InAdjacencyList);
            context.AddField(Alias.Value, "*", ColumnGraphType.VertexObject);
            for (var i = GraphViewReservedProperties.ReservedNodeProperties.Count; i < projectedField.Count; i++)
            {
                context.AddField(Alias.Value, projectedField[i], ColumnGraphType.Value);
            }

            return(addVOp);
        }
Ejemplo n.º 29
0
 public GraphViewCommand(string commandText, GraphViewConnection connection)
 {
     CommandText = commandText;
     Connection = connection;
     Command = Connection.Conn.CreateCommand();
 }
Ejemplo n.º 30
0
        //  This is a tutorial for GraphView user showing how to insert or delete nodes and edges
        //  Please notice that following script will drop all the table in databse when it finished
        public static void run()
        {
            GraphViewConnection con = new GraphViewConnection( TutorialConfiguration.getConnectionString());
            con.Open();
            con.ClearData();
            try
            {
                #region Create a schema for node
                con.CreateNodeTable(@"CREATE TABLE [People] ( 
                    [ColumnRole:""NodeId""] id INT, 
                    [ColumnRole:""Property""] name varchar(20), 
                    [ColumnRole:""Edge"",Reference:""People""] Knows VARBINARY(max) )");
                System.Console.WriteLine("Create table successed!");
                #endregion

                #region Create nodes
                con.ExecuteNonQuery("INSERT INTO [People](id,name) VALUES(1,'Alice')");
                con.ExecuteNonQuery("INSERT INTO [People](id,name) VALUES(2,'Bob')");
                con.ExecuteNonQuery("INSERT INTO [People](id,name) VALUES(3,'Caven')");
                con.ExecuteNonQuery("INSERT INTO [People](id,name) VALUES(4,'David')");
                //  You must insert with ColumnRole 'NodeId' if you have
                //  i.e. Following insertion is invalid
                //  con.ExecuteNonQuery("INSERT INTO [People](name) VALUES('Eva')");
                #endregion

                #region Insert edges

                // Alice knows Bob
                con.ExecuteNonQuery(@"INSERT EDGE INTO People.Knows
                                    SELECT x,y FROM People x , People y 
                                        WHERE x.name = 'Alice' AND y.name = 'Bob' ");
                // Bob knows Caven
                con.ExecuteNonQuery(@"INSERT EDGE INTO People.Knows
                                    SELECT x,y FROM People x , People y 
                                        WHERE x.name = 'Bob' AND y.name = 'caven' ");

                // Bob knows David
                con.ExecuteNonQuery(@"INSERT EDGE INTO People.Knows
                                    SELECT x,y FROM People x , People y 
                                        WHERE x.name = 'Bob' AND y.name = 'David' ");
                #endregion

                #region Query 1: find out knowers of knowers

                System.Console.WriteLine("\nQuery 1:");

                var res = con.ExecuteReader(@"SELECT C.* FROM People A, People B, People C
                                MATCH A-[Knows]->B-[Knows]->C
                                WHERE A.name = 'Alice' ");
                try
                {

                    while (res.Read())
                    {
                        System.Console.WriteLine("Name: " + res["name"].ToString());
                    }
                }
                finally
                {
                    if (res != null)
                        res.Close();
                }
                #endregion

                #region Delete edges
                con.ExecuteNonQuery(@"DELETE EDGE [x]-[Knows]->[y] 
                                        FROM People as x, People as y
                                        WHERE y.name='Bob' or y.name = 'Caven' ");
                #endregion

                #region Query 2: find out all edges
                System.Console.WriteLine("\nQuery 2:");

                res = con.ExecuteReader(@"SELECT x.name as name1, y.name as name2 FROM People x, People y
                                MATCH x-[Knows]->y ");

                try
                {
                    while (res.Read())
                    {
                        System.Console.WriteLine(res["name1"].ToString() + " knows " + res["name2"].ToString());
                    }
                }
                finally
                {
                    if (res != null)
                        res.Close();
                }
                #endregion

                #region Delete node
                con.ExecuteNonQuery("DELETE NODE FROM People WHERE People.name <> 'Bob' and People.name <> 'David' "); //  Try to delete all nodes.
                //  Notice that you can not delete a node with edge linked to it.
                //  Above query will not delete Bob and David since there's an edge from Bob to David
                #endregion

                #region Query 3: find out remaining nodes
                System.Console.WriteLine("\nQuery 3:");
                res = con.ExecuteReader("SELECT * FROM [People] ");
                try
                {
                    while (res.Read())
                    {
                        System.Console.WriteLine(res["name"].ToString());
                    }
                }
                finally
                {
                    if (res != null)
                        res.Close();
                }
                #endregion

                #region Delete all edges and nodes
                con.ExecuteNonQuery(@"DELETE EDGE [x]-[Knows]->[y] 
                                        FROM People as x, People as y ");
                con.ExecuteNonQuery("DELETE NODE FROM People ");
                #endregion

                #region Query 4: find out remaining nodes
                System.Console.WriteLine("\nQuery 4:");
                res = con.ExecuteReader("SELECT * FROM [People] ");
                try
                {
                    while (res.Read())
                    {
                        System.Console.WriteLine(res["name"].ToString());
                    }
                    System.Console.WriteLine("Result should be empty");
                }
                finally
                {
                    if (res != null)
                        res.Close();
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }
            finally //  close the connection and drop table
            {
                // Drop table and clear all the data
                con.ClearGraphDatabase();
                con.Close();
            }
        }
Ejemplo n.º 31
0
        /// <summary>
        /// This function spills a small-degree vertex, stores its edges into seperate documents
        /// Either its incoming or outgoing edges are moved to a new document, decided by which is larger in size
        /// NOTE: This function will upload the vertex document
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="vertexObject"></param>
        /// <param name="existEdgeDocId">This is the first edge-document (to store the existing edges)</param>
        /// <param name="newEdgeDocId">This is the second edge-document (to store the currently creating edge)</param>
        private static void SpillVertexEdgesToDocument(GraphViewConnection connection, JObject vertexObject, out string existEdgeDocId, out string newEdgeDocId)
        {
            Debug.Assert(vertexObject["_partition"] != null);
            Debug.Assert((string)vertexObject["id"] == (string)vertexObject["_partition"]);

            // NOTE: The VertexCache is not updated here
            bool outEdgeSeperated = vertexObject["_edge"] is JObject;
            bool inEdgeSeperated  = vertexObject["_reverse_edge"] is JObject;

            if (inEdgeSeperated && outEdgeSeperated)
            {
                throw new Exception("BUG: Should not get here! Either incoming or outgoing edegs should not have been seperated");
            }

            JArray targetEdgeArray;
            bool   targetEdgeIsReverse;

            if (inEdgeSeperated)
            {
                targetEdgeArray     = (JArray)vertexObject["_edge"];
                targetEdgeIsReverse = false;
            }
            else if (outEdgeSeperated)
            {
                targetEdgeArray     = (JArray)vertexObject["_reverse_edge"];
                targetEdgeIsReverse = true;
            }
            else
            {
                JArray outEdgeArray = (JArray)vertexObject["_edge"];
                JArray inEdgeArray  = (JArray)vertexObject["_reverse_edge"];
                targetEdgeIsReverse = (outEdgeArray.ToString().Length < inEdgeArray.ToString().Length);
                targetEdgeArray     = targetEdgeIsReverse ? inEdgeArray : outEdgeArray;
            }

            // Create a new edge-document to store the currently creating edge
            JObject newEdgeDocObject = new JObject {
                ["id"]          = GraphViewConnection.GenerateDocumentId(),
                ["_partition"]  = vertexObject["_partition"],
                ["_is_reverse"] = targetEdgeIsReverse,
                ["_is_reverse"] = targetEdgeIsReverse,
                ["_vertex_id"]  = (string)vertexObject["id"],
                ["_edge"]       = new JArray(targetEdgeArray.Last),
            };

            newEdgeDocId = connection.CreateDocumentAsync(newEdgeDocObject).Result;
            targetEdgeArray.Last.Remove();  // Remove the currently create edge appended just now

            // Create another new edge-document to store the existing edges.
            JObject existEdgeDocObject = new JObject {
                ["id"]          = GraphViewConnection.GenerateDocumentId(),
                ["_partition"]  = vertexObject["_partition"],
                ["_is_reverse"] = targetEdgeIsReverse,
                ["_vertex_id"]  = (string)vertexObject["id"],
                ["_edge"]       = targetEdgeArray,
            };

            existEdgeDocId = connection.CreateDocumentAsync(existEdgeDocObject).Result;

            // Update vertexObject to store the newly create edge-document & upload the vertexObject
            vertexObject[targetEdgeIsReverse ? "_reverse_edge" : "_edge"] = new JObject {
                ["_edges"] = new JArray {
                    new JObject {
                        ["id"] = existEdgeDocId,
                    },
                    new JObject {
                        ["id"] = newEdgeDocId,
                    },
                },
            };
            bool dummyTooLarge;

            UploadOne(connection, (string)vertexObject["id"], vertexObject, out dummyTooLarge);
        }
Ejemplo n.º 32
0
        public static void RemoveEdge(
            Dictionary <string, Tuple <JObject, string> > documentMap,
            GraphViewConnection connection,
            string edgeDocId,
            JObject vertexObject,
            bool isReverse,
            string srcVertexId, long edgeOffset)
        {
            JToken edgeContainer = vertexObject[isReverse ? "_reverse_edge" : "_edge"];

            if (edgeContainer is JObject)
            {
                // Now it is a large-degree vertex, and contains at least 1 edge-document
                Debug.Assert(!string.IsNullOrEmpty(edgeDocId), "!string.IsNullOrEmpty(edgeDocId)");

                JArray edgeDocumentsArray = (JArray)edgeContainer["_edges"];
                Debug.Assert(edgeDocumentsArray != null, "edgeDocuments != null");
                Debug.Assert(edgeDocumentsArray.Count > 0, "edgeDocuments.Count > 0");

                JObject edgeDocument = connection.RetrieveDocumentById(edgeDocId);
                Debug.Assert(edgeDocument["_partition"] != null);
                Debug.Assert(vertexObject["_partition"] != null);
                Debug.Assert(((string)edgeDocument["id"]).Equals(edgeDocId), "((string)edgeDocument['id']).Equals(edgeDocId)");
                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']");

                // The edge to be removed must exist! (garanteed by caller)
                JArray edgesArray = (JArray)edgeDocument["_edge"];
                Debug.Assert(edgesArray != null, "edgesArray != null");
                Debug.Assert(edgesArray.Count > 0, "edgesArray.Count > 0");
                if (isReverse)
                {
                    edgesArray.First(e => (string)e["_srcV"] == srcVertexId && (long)e["_offset"] == edgeOffset).Remove();
                }
                else
                {
                    edgesArray.First(e => (long)e["_offset"] == edgeOffset).Remove();
                }

                //
                // If the edge-document contains no edge after the removal, delete this edge-document.
                // Don't forget to update the vertex-document at the same time.
                //
                if (edgesArray.Count == 0)
                {
                    edgeDocumentsArray.First(edoc => ((string)edoc["id"]).Equals(edgeDocId)).Remove();

                    //
                    // If the vertex-document contains no (incoming or outgoing) edges now, set edgeContainer
                    // ("_edge" or "_reverse_edge") to an empry JArray! Anyway, we ensure that if edgeContainer
                    // is JObject, it contains at least one edge-document
                    //
                    if (edgeDocumentsArray.Count == 0)
                    {
                        vertexObject[isReverse ? "_reverse_edge" : "_edge"] = new JArray();
                    }

                    // Delete the edge-document, and add the vertex-document to the upload list
                    documentMap[edgeDocId] = new Tuple <JObject, string>(null, (string)edgeDocument["_partition"]);
                    documentMap[(string)vertexObject["id"]] = new Tuple <JObject, string>(vertexObject, (string)vertexObject["_partition"]);
                }
                else
                {
                    documentMap[edgeDocId] = new Tuple <JObject, string>(edgeDocument, (string)edgeDocument["_partition"]);
                }
            }
            else if (edgeContainer is JArray)
            {
                Debug.Assert(edgeDocId == null, "edgeDocId == null");

                if (isReverse)
                {
                    ((JArray)edgeContainer).First(e => (string)e["_srcV"] == srcVertexId && (long)e["_offset"] == edgeOffset).Remove();
                }
                else
                {
                    ((JArray)edgeContainer).First(e => (long)e["_offset"] == edgeOffset).Remove();
                }
                documentMap[(string)vertexObject["id"]] = new Tuple <JObject, string>(vertexObject, (string)vertexObject["_partition"]);
            }
            else
            {
                throw new Exception($"BUG: edgeContainer should either be JObject or JArray, but now: {edgeContainer?.GetType()}");
            }
        }
Ejemplo n.º 33
0
        //  This is a tutorial for GraphView user about how to create SP and execute SP
        //  Using SP is much more faster than call GraphViewConnection.executeNonQuery()
        //  We highly recommend you create SP for the queries
        //  Please notice that following script will drop all the table in database when it finished
        
        public static void run()
        {
            GraphViewConnection con = new GraphViewConnection(TutorialConfiguration.getConnectionString());
            con.Open();
            con.ClearData();
            try
            {
                #region Create a schema for node
                con.CreateNodeTable(@"CREATE TABLE [Node] ( 
                    [ColumnRole:""NodeId""] id INT, 
                    [ColumnRole:""Edge"",Reference:""Node""] Edges VARBINARY(max) )");
                System.Console.WriteLine("Create table successed!");

                #endregion

                #region Create nodes
                con.ExecuteNonQuery("INSERT INTO [Node](id) VALUES(1)");
                con.ExecuteNonQuery("INSERT INTO [Node](id) VALUES(2)");
                con.ExecuteNonQuery("INSERT INTO [Node](id) VALUES(3)");
                #endregion

                #region Create SP
                con.CreateProcedure(@"CREATE PROCEDURE AddEdge
                        @st INT,
                        @ed INT
                        AS
                        BEGIN
                            INSERT EDGE INTO Node.Edges
                            SELECT s,t FROM
                            Node s , Node t WHERE s.id = @st AND t.id= @ed ;
                        END");
                con.CreateProcedure(@"CREATE PROCEDURE SelectNeighbors
                        @id INT
                        AS
                        BEGIN
                            SELECT y.* FROM Node x, Node y
                                MATCH x-[Edges]->y
                                WHERE x.id = @id
                        END");

                #endregion

                #region Using SP to insert edges
                using (var command = con.CreateCommand())
                {
                    command.CommandType = System.Data.CommandType.StoredProcedure;
                    command.CommandText = "AddEdge";
                    command.Parameters.AddWithValue("@st", 1);
                    command.Parameters.AddWithValue("@ed", 2);
                    command.ExecuteNonQuery();

                    command.Parameters.Clear();
                    command.Parameters.AddWithValue("@st", 1);
                    command.Parameters.AddWithValue("@ed", 3);
                    command.ExecuteNonQuery();
                }
                #endregion

                #region Using SP to query
                using (var command = con.CreateCommand())
                {
                    command.CommandType = System.Data.CommandType.StoredProcedure;
                    command.CommandText = "SelectNeighbors";
                    command.Parameters.AddWithValue("@id", 1);
                    var res = command.ExecuteReader();
                    try
                    {
                        while (res.Read())
                        {
                            System.Console.WriteLine(res["id"].ToString());
                        }
                    }
                    finally
                    {
                        if (res != null)
                            res.Close();
                    }
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }
            finally //  close the connection and drop table
            {
                con.ClearGraphDatabase();
                con.Close();
            }
        }
Ejemplo n.º 34
0
        public static Dictionary <string, AdjacencyListField> GetReverseAdjacencyListsOfVertexCollection(GraphViewConnection connection, HashSet <string> vertexIdSet)
        {
            Dictionary <string, AdjacencyListField> revAdjacencyListCollection = new Dictionary <string, AdjacencyListField>();

            StringBuilder vertexIdList = new StringBuilder();

            foreach (string vertexId in vertexIdSet)
            {
                if (vertexIdList.Length > 0)
                {
                    vertexIdList.Append(", ");
                }
                vertexIdList.AppendFormat("'{0}'", vertexId);

                revAdjacencyListCollection[vertexId] = new AdjacencyListField();
            }

            string query = $"SELECT {{\"edge\": edge, " +
                           $"\"vertexId\": edge._sinkV, " +
                           $"\"_srcV\": doc.id, " +
                           $"\"_srcVLabel\": doc.label}} AS incomingEdgeMetadata\n" +
                           $"FROM doc\n" +
                           $"JOIN edge IN doc._edge\n" +
                           $"WHERE edge._sinkV IN ({vertexIdList.ToString()})\n";

            foreach (JObject edgeDocument in connection.ExecuteQuery(query))
            {
                JObject edgeMetadata = (JObject)edgeDocument["incomingEdgeMetadata"];
                JObject edgeObject   = (JObject)edgeMetadata["edge"];
                string  vertexId     = edgeMetadata["vertexId"].ToString();
                string  srcV         = edgeMetadata["_srcV"].ToString();
                string  srcVLabel    = edgeMetadata["_srcVLabel"]?.ToString();

                EdgeField edgeField = EdgeField.ConstructForwardEdgeField(srcV, srcVLabel, null, edgeObject);
                edgeField.EdgeProperties.Add("_srcV", new EdgePropertyField("_srcV", srcV, JsonDataType.String, edgeField));
                if (srcVLabel != null)
                {
                    edgeField.EdgeProperties.Add("_srcVLabel",
                                                 new EdgePropertyField("_srcVLabel", srcVLabel, JsonDataType.String, edgeField));
                }

                AdjacencyListField revAdjList = revAdjacencyListCollection[vertexId];
                revAdjList.AddEdgeField(srcV, (long)edgeObject["_offset"], edgeField);
            }

            return(revAdjacencyListCollection);
        }
Ejemplo n.º 35
0
 public GraphTraversal2(GraphViewConnection connection, OutputFormat outputFormat)
 {
     GremlinTranslationOpList = new List <GremlinTranslationOperator>();
     Connection        = connection;
     this.outputFormat = outputFormat;
 }