/// <summary> /// Try to detect if the Element is a Vertex or an Edge /// If we are not provided with interfaces, we need to have an /// Type that has a default constructor, to use /// GraphSerializerFactory to create a Serializer which knows about this. /// </summary> /// <param name="t"></param> /// <returns></returns> internal static GraphElementType GetElementType(Type t) { Type[] interfaces = t.GetInterfaces(); var vInterface = interfaces.Where(i => i.Name == typeof(IVertex <object, object>).Name).FirstOrDefault(); if (vInterface != null) { return(GraphElementType.Vertex); } var eInterface = interfaces.Where(i => i.Name == typeof(IEdge <object, object>).Name).FirstOrDefault(); if (eInterface != null) { return(GraphElementType.Edge); } if (t.GetConstructor(Type.EmptyTypes) != null) { IGraphSerializer serializer = GraphSerializerFactory.CreateGraphSerializer(null, t); if (serializer.IsEdge()) { return(GraphElementType.Edge); } else { return(GraphElementType.Vertex); } } throw new Exception("Could not determine element type!"); }
public SaveLoadGraph(Logs log, IGraphSerializer graphSerializer, IPathInput pathInput) { this.graphSerializer = graphSerializer; this.pathInput = pathInput; this.log = log; }
internal static IGraphSerializer CreateGraphSerializer(IGraphContext context, Type itemType) { if (context == null) { context = myDefaultGraphContext; } if (CreateGraphSerializerMethodInfo == null) { MethodInfo[] methods = typeof(GraphSerializerFactory).GetMethods(); foreach (MethodInfo mi in methods.Where(m => m.Name == "CreateGraphSerializer" && m.IsGenericMethod == true)) { var parameters = mi.GetParameters(); if (parameters.Length > 0) { CreateGraphSerializerMethodInfo = mi; break; } } } if (!mySerializers.ContainsKey(context)) { mySerializers.Add(context, new Dictionary <Type, object>()); } if (mySerializers[context].ContainsKey(itemType)) { return(mySerializers[context][itemType] as IGraphSerializer); } MethodInfo generic = CreateGraphSerializerMethodInfo.MakeGenericMethod(itemType); IGraphSerializer serializer = generic.Invoke(null, new object[] { context }) as IGraphSerializer; return(serializer); }
public static async Task <List <ResourceResponse <Document> > > UpsertGraphDocumentsAsync(this DocumentClient client, DocumentCollection collection, IEnumerable items) { List <ResourceResponse <Document> > results = new List <ResourceResponse <Document> >(); foreach (object poco in items) { IGraphSerializer serializer = GraphSerializerFactory.CreateGraphSerializer(null, poco.GetType()); results.Add(await client.UpsertDocumentAsync(collection.SelfLink, serializer.ConvertToDocDBJObject(poco))); } return(results); }
public MainViewModel( BaseGraphFieldFactory fieldFactory, IVertexEventHolder eventHolder, IGraphSerializer graphSerializer, IGraphAssemble graphFactory, IPathInput pathInput, IAssembleClasses assembleClasses, Logs log) : base(fieldFactory, eventHolder, graphSerializer, graphFactory, pathInput, assembleClasses, log) { }
/// <summary> /// Works simmilar to ExecuteNextAsyc<T> from IDocumentQuery<T> and allows to deserialize the results /// to custom objects of type T /// </summary> /// <typeparam name="T"></typeparam> /// <param name="gremlinQuery">ExtensionObject IDocumentQuery</param> /// <param name="context">Context that can store GraphElements. If you retrieved vertices and then an edge refering to those vertices they will be automatically linked.</param> /// <returns></returns> public static async Task <IList <T> > ExecuteNextAsyncAsPOCO <T>(this IDocumentQuery gremlinQuery, IGraphContext context = null) // where T : new() { List <T> result = new List <T>(); IGraphSerializer serializer = null; Type targetType = typeof(T); if (gremlinQuery.GetType().GenericTypeArguments[0] != typeof(Vertex)) { IDocumentQuery <Edge> edgeQuery = gremlinQuery as IDocumentQuery <Edge>; var resultSet = await edgeQuery.ExecuteNextAsync <Edge>(); foreach (Edge e in resultSet) { string typeString = GraphSerializer.GetTypePropertyString(e, out string inVTypeString, out string outVTypeString); if (String.IsNullOrEmpty(typeString)) { serializer = GraphSerializerFactory.CreateGraphSerializer(context, targetType); // Try to instantiate T } else { serializer = GraphSerializerFactory.CreateGraphSerializer(context, typeString); } serializer.Convert(e, out object edge); result.Add((T)edge); } } else { IDocumentQuery <Vertex> vertexQuery = gremlinQuery as IDocumentQuery <Vertex>; var resultSet = await vertexQuery.ExecuteNextAsync <Vertex>(); foreach (Vertex v in resultSet) { string typeString = GraphSerializer.GetTypePropertyString(v); if (String.IsNullOrEmpty(typeString)) { serializer = GraphSerializerFactory.CreateGraphSerializer(context, targetType); // Try to instantiate T } else { serializer = GraphSerializerFactory.CreateGraphSerializer(context, typeString); } serializer.Convert(v, out object vertex); result.Add((T)vertex); } } return(result); }
protected MainModel(BaseGraphFieldFactory fieldFactory, IVertexEventHolder eventHolder, IGraphSerializer graphSerializer, IGraphAssemble graphAssembler, IPathInput pathInput, IAssembleClasses assembleClasses, ILog log) { this.eventHolder = eventHolder; serializer = graphSerializer; graphSerializer.OnExceptionCaught += log.Warn; this.fieldFactory = fieldFactory; this.graphAssembler = graphAssembler; this.pathInput = pathInput; this.assembleClasses = assembleClasses; this.log = log; Graph = new NullGraph(); }
public async Task TestSimple() { Simple.Place cave = new Simple.Place() { name = "Cave of Hobbit" }; Simple.Place restaurant = new Simple.Place() { name = "Restaurant Green Dragon" }; Simple.Place europe = new Simple.Place() { name = "Europe", country = GraphProperty.Create("country", "AT", "MetaTag1", "Austria").AddValue("FI", "MetaTag1", "Finnland") }; Simple.Path hobbitPath = new Simple.Path(cave, restaurant, 2); //TODO: find out why 2.3 has an issue await client.CreateGraphDocumentAsync <Simple.Place>(collection, cave); await client.CreateGraphDocumentAsync <Simple.Place>(collection, restaurant); await client.CreateGraphDocumentAsync <Simple.Place>(collection, europe); await client.CreateGraphDocumentAsync <Simple.Path>(collection, hobbitPath); MemoryGraph partialGraph = new MemoryGraph(); string gremlinQueryStatement = "g.V().hasLabel('place')"; Console.WriteLine($"Executing gremlin query as string: {gremlinQueryStatement}"); var germlinQuery = client.CreateGremlinQuery <Vertex>(collection, gremlinQueryStatement); while (germlinQuery.HasMoreResults) { // It is not required to pass in a context like partialGraph here. This parameter can be omitted. foreach (var result in await germlinQuery.ExecuteNextAsyncAsPOCO <Simple.Place>(partialGraph)) { Console.WriteLine($"Vertex ==> Label:{result.Label} Name:{result.name}"); } } #region EXPERIMENTAL DEMO /// ================================================================================================= /// IMPORTANT: The following code makes use of the internal GraphTraversal class, which should not /// be used according to the documentation of Microsofts Graph Library. Use at your own risk. /// ================================================================================================= // Connect with GraphConnection object graphConnection = GraphConnectionFactory.Create(client, collection); // Drop previous context (optional if the same graph) partialGraph.Drop(); Microsoft.Azure.Graphs.GraphCommand cmd = GraphCommandFactory.Create(graphConnection); GraphTraversal placeTrav = cmd.g().V().HasLabel("place"); GraphTraversal edgeTrav = cmd.g().E().HasLabel("path"); { Console.WriteLine("Retrieving all places with 'NextAsPOCO'-Extension on GraphTraversal "); // Returns a list of all vertices for place var places = await placeTrav.NextAsPOCO <Simple.Place>(partialGraph); foreach (Simple.Place place in places) { Console.WriteLine($"Vertex ==> Label:{place.Label} Name:{place.name}"); } } // Drop previous context (optional if the same graph) partialGraph.Drop(); IGraphSerializer <Simple.Place> placeGraphSerializer = GraphSerializerFactory.CreateGraphSerializer <Simple.Place>(partialGraph); foreach (var p in placeTrav) { IList <Simple.Place> places = placeGraphSerializer.DeserializeGraphSON(p); // Returns more than one result in each call foreach (Simple.Place place in places) { Console.WriteLine($"Vertex ==> Label:{place.Label} Name:{place.name}"); Console.WriteLine("Serializing to CosmosDB internal represenation: "); string docDBJson = placeGraphSerializer.ConvertToDocDBJObject(place).ToString(); Console.WriteLine($"JSON ==> {docDBJson}"); } } Console.WriteLine("Iterating over GraphTraversal Paths (Edges) and deserializing GraphSON to custom object "); IGraphSerializer <Simple.Path> pathGraphSerializer = GraphSerializerFactory.CreateGraphSerializer <Simple.Path>(partialGraph); foreach (var p in edgeTrav) { IList <Simple.Path> paths = pathGraphSerializer.DeserializeGraphSON(p); // Returns more than one result in each loop foreach (Simple.Path path in paths) { Console.WriteLine($"Edge ==> Label:{path.Label} Weight:{path.weight}"); Console.WriteLine("Serializing to CosmosDB internal represenation: "); string docDBJson = pathGraphSerializer.ConvertToDocDBJObject(path).ToString(); Console.WriteLine($"JSON ==> {docDBJson}"); } } #endregion }
public Generator(IGraphSerializer graphSerializer) { //_fileReader = fileReader; _graphSerializer = graphSerializer; }
/// <summary> /// Can be called on a GraphTraversal to retrieve Vertices or Edges as custom objects. /// </summary> /// <typeparam name="T">Type of custom object that represents the Vertex or Edge</typeparam> /// <param name="trav">Extension Object GraphTraversal</param> /// <param name="context">Context that can store GraphElements. If you retrieved vertices and then an edge refering to those vertices they will be automatically linked.</param> /// <returns></returns> public static async Task <IList <T> > NextAsPOCO <T>(this GraphTraversal trav, IGraphContext context = null) // where T : new() { IGraphSerializer serializer = null; List <T> result = new List <T>(); /// Verify if the OutputFormat of the GraphCommand was set to GraphSON! Type graphTraversalType = typeof(GraphTraversal); Type targetType = typeof(T); FieldInfo outputFormatPropertyInfo = graphTraversalType.GetField("outputFormat", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); string outputFormat = outputFormatPropertyInfo.GetValue(trav).ToString(); if (!outputFormat.StartsWith("GraphSON")) { throw new Exception("OutputFormat of GraphCommand needs to be set to GRAPHSON!"); } // GraphSerializer<T> serializer = GraphSerializerFactory.CreateGraphSerializer<T>(context); // Edges and Vertices must be treated separately if (GraphSerializer.GetElementType(typeof(T)) == GraphElementType.Edge) { List <Edge> resultSet = await trav.NextAsModelAsync <Edge>(); foreach (Edge e in resultSet) { string typeString = GraphSerializer.GetTypePropertyString(e, out string inVTypeString, out string outVTypeString); if (String.IsNullOrEmpty(typeString)) { serializer = GraphSerializerFactory.CreateGraphSerializer(context, targetType); // Try to instantiate T } else { serializer = GraphSerializerFactory.CreateGraphSerializer(context, typeString); } serializer.Convert(e, out object edge); result.Add((T)edge); } } else { List <Vertex> resultSet = await trav.NextAsModelAsync <Vertex>(); foreach (Vertex v in resultSet) { string typeString = GraphSerializer.GetTypePropertyString(v); if (String.IsNullOrEmpty(typeString)) { serializer = GraphSerializerFactory.CreateGraphSerializer(context, targetType); // Try to instantiate T } else { serializer = GraphSerializerFactory.CreateGraphSerializer(context, typeString); } serializer.Convert(v, out object vertex); result.Add((T)vertex); } //Alternative implementation TODO: Measure speed //========================== //foreach (var graphSON in trav) //{ // List<T> partialResult = serializer.DeserializeGraphSON(graphSON); // foreach (T r in partialResult) // result.Add(r); //} } return(result); }
public static async Task <ResourceResponse <Document> > UpsertGraphDocumentAsync <T>(this DocumentClient client, DocumentCollection collection, T poco) { IGraphSerializer serializer = GraphSerializerFactory.CreateGraphSerializer(null, poco.GetType()); return(await client.UpsertDocumentAsync(collection.SelfLink, serializer.ConvertToDocDBJObject(poco))); }
public static async Task <ResourceResponse <Document> > CreateGraphDocumentAsync <T>(this DocumentClient client, DocumentCollection collection, T poco) where T : new() { IGraphSerializer <T> serializer = GraphSerializerFactory.CreateGraphSerializer <T>(); return(await client.CreateDocumentAsync(collection.SelfLink, serializer.ConvertToDocDBJObject(poco))); }
static async Task Demo() { try { Console.WriteLine("========================================================="); Console.WriteLine("Demo for the SpectoLogic.Azure.CosmosDB Extension Library"); Console.WriteLine("(c) by SpectoLogic e.U. 2017"); Console.WriteLine("written by Andreas Pollak"); Console.WriteLine("Licensed under the MIT License"); Console.WriteLine("========================================================="); // Connect with DocumentClient and create necessary Database and Collection Console.Write("Creating Collection 'thehobbit'..."); DocumentClient client = await CosmosDBHelper.ConnectToCosmosDB(Account_DemoBuild_Hobbit, Account_DemoBuild_Hobbit_Key); Database db = await CosmosDBHelper.CreateOrGetDatabase(client, "demodb"); DocumentCollection collection = await CosmosDBHelper.CreateCollection(client, db, "thehobbit", 400, null, null, false); Console.WriteLine("Done"); Console.WriteLine("---------------------------------------------------------"); Console.WriteLine("DEMO: Delivery Demo "); Console.WriteLine("---------------------------------------------------------"); Delivery.Demo d = new Delivery.Demo(); await d.Execute(client, collection); Console.WriteLine("---------------------------------------------------------"); Console.WriteLine("DEMO: Create custom objects and populate cosmosdb graph"); Console.WriteLine("---------------------------------------------------------"); Place cave = new Place() { name = "Cave of Hobbit" }; Place restaurant = new Place() { name = "Restaurant Green Dragon" }; Place europe = new Place() { name = "Europe", country = GraphProperty.Create("country", "AT", "MetaTag1", "Austria").AddValue("FI", "MetaTag1", "Finnland") }; Path hobbitPath = new Path(cave, restaurant, 2); //TODO: find out why 2.3 has an issue await client.CreateGraphDocumentAsync <Place>(collection, cave); await client.CreateGraphDocumentAsync <Place>(collection, restaurant); await client.CreateGraphDocumentAsync <Place>(collection, europe); await client.CreateGraphDocumentAsync <Path>(collection, hobbitPath); Console.WriteLine("----------------------------------------------------------------------------------"); Console.WriteLine("DEMO: Usage of 'ExecuteNextAsyncAsPOCO<T>'-Extension Method on typed Gremlin Query"); Console.WriteLine("----------------------------------------------------------------------------------"); MemoryGraph partialGraph = new MemoryGraph(); string gremlinQueryStatement = "g.V().hasLabel('place')"; Console.WriteLine($"Executing gremlin query as string: {gremlinQueryStatement}"); var germlinQuery = client.CreateGremlinQuery <Vertex>(collection, gremlinQueryStatement); while (germlinQuery.HasMoreResults) { // It is not required to pass in a context like partialGraph here. This parameter can be omitted. foreach (var result in await germlinQuery.ExecuteNextAsyncAsPOCO <Place>(partialGraph)) { Console.WriteLine($"Vertex ==> Label:{result.Label} Name:{result.name}"); } } #region EXPERIMENTAL DEMO /// ================================================================================================= /// IMPORTANT: The following code makes use of the internal GraphTraversal class, which should not /// be used according to the documentation of Microsofts Graph Library. Use at your own risk. /// ================================================================================================= Console.WriteLine("--------------------------------------------------------------------"); Console.WriteLine("DEMO: Usage of 'NextAsPOCO<T>' with GraphCommand and GraphTraversal "); Console.WriteLine("--------------------------------------------------------------------"); Console.Write("Connecting with GraphConnection object..."); // Connect with GraphConnection object graphConnection = GraphConnectionFactory.Create(client, collection); Console.WriteLine("Done"); // Drop previous context (optional if the same graph) partialGraph.Drop(); Microsoft.Azure.Graphs.GraphCommand cmd = GraphCommandFactory.Create(graphConnection); GraphTraversal placeTrav = cmd.g().V().HasLabel("place"); GraphTraversal edgeTrav = cmd.g().E().HasLabel("path"); { Console.WriteLine("Retrieving all places with 'NextAsPOCO'-Extension on GraphTraversal "); // Returns a list of all vertices for place var places = await placeTrav.NextAsPOCO <Place>(partialGraph); foreach (Place place in places) { Console.WriteLine($"Vertex ==> Label:{place.Label} Name:{place.name}"); } } Console.WriteLine("--------------------------------------------------------------------"); Console.WriteLine("DEMO: Direct Usage of GraphSerializer<T> with GraphTraversal "); Console.WriteLine("--------------------------------------------------------------------"); // Drop previous context (optional if the same graph) partialGraph.Drop(); Console.WriteLine("Iterating over GraphTraversal Places (Vertices) and deserializing GraphSON to custom object "); IGraphSerializer <Place> placeGraphSerializer = GraphSerializerFactory.CreateGraphSerializer <Place>(partialGraph); foreach (var p in placeTrav) { IList <Place> places = placeGraphSerializer.DeserializeGraphSON(p); // Returns more than one result in each call foreach (Place place in places) { Console.WriteLine($"Vertex ==> Label:{place.Label} Name:{place.name}"); Console.WriteLine("Serializing to CosmosDB internal represenation: "); string docDBJson = placeGraphSerializer.ConvertToDocDBJObject(place).ToString(); Console.WriteLine($"JSON ==> {docDBJson}"); } } Console.WriteLine("Iterating over GraphTraversal Paths (Edges) and deserializing GraphSON to custom object "); IGraphSerializer <Path> pathGraphSerializer = GraphSerializerFactory.CreateGraphSerializer <Path>(partialGraph); foreach (var p in edgeTrav) { IList <Path> paths = pathGraphSerializer.DeserializeGraphSON(p); // Returns more than one result in each loop foreach (Path path in paths) { Console.WriteLine($"Edge ==> Label:{path.Label} Weight:{path.weight}"); Console.WriteLine("Serializing to CosmosDB internal represenation: "); string docDBJson = pathGraphSerializer.ConvertToDocDBJObject(path).ToString(); Console.WriteLine($"JSON ==> {docDBJson}"); } } #endregion } catch (Exception ex) { Console.WriteLine("\nError:"); Console.WriteLine($"Demo failed with {ex.Message}."); } }