/// <summary> /// Add simple index on type property. /// </summary> public static void AddIndex(this IStatementRunner statementRunner, string typeName, string propertyName) { propertyName = propertyName.ToCamelCase(); var statement = $"CREATE INDEX ON: {typeName}({propertyName})"; statementRunner.Run(statement); }
private void DeleteIndexes(IStatementRunner runner) { var indexResult = runner.Run("CALL db.indexes()"); using (var enumerator = indexResult.GetEnumerator()) { while (enumerator.MoveNext()) { var record = enumerator.Current; if (record != null) { var statement = $"DROP {record.Values["description"]} "; runner.Run(statement); } } } }
private IResultSummary Execute(IStatementRunner runner, string statement) { var result = runner.Run(statement); Thread.Sleep(_rnd.Next(100)); result.Summary(); Thread.Sleep(_rnd.Next(100)); return(result.Summary()); }
public static IEnumerable <T> Query <T>(this IStatementRunner session, string cypher) { var forLookup = new PreparedStatement <T>(cypher); var ps = (PreparedStatement <T>)PreparedStatements.GetOrAdd(forLookup.GetHashCode(), hash => forLookup); foreach (var record in session.Run(cypher)) { yield return(ps.Map(record)); } }
private void DeleteNodes(IStatementRunner runner) { int deletedNodes; do { var statement = $"MATCH (n) WITH n LIMIT {BatchSizeDelete} DETACH DELETE n"; var result = runner.Run(statement); deletedNodes = result.Summary.Counters.NodesDeleted; } while (deletedNodes == BatchSizeDelete); }
private IList <Edge> GetEdges(IStatementRunner runner) { log.Debug("Retrieving edges..."); var result = runner.Run(GetEdgesCypher); log.Debug("Done."); return(result.Select(rec => new Edge { Vertex1 = Convert.ToInt32(rec["n.id"]), Vertex2 = Convert.ToInt32(rec["m.id"]) }).ToList()); }
/// <summary> /// Add POCO object as node in Neo4j database. /// All public properties will automatically be added as properties of the node. /// Please note that it is NOT merely a concatenated string that is executed! /// To avoid injection attacks the parameters are properly inserted through a value array. /// </summary> /// <param name="statementRunner">Either a session or a transation to execute the statement</param> /// <param name="obj">Generic POCO object</param> /// <param name="label">Specify type name to be used. Skip if you are satisfied with object type name.</param> /// <param name="i">Optional counter if used from collection. Only used for logging.</param> public static int AddNode(this IStatementRunner statementRunner, object obj, string label, int?i = null) { // CREATE (:TypeName { propertyName1: propertyValue, propertyName2: propertyValue2 } )"; label = label ?? obj.GetType().Name; var parameters = obj.GetProperties(); var valuePairs = string.Join(", ", parameters.Select(p => $"{p.Key}: {{{p.Key}}}")); var statement = $"CREATE (x:{label} {{{valuePairs}}} ) RETURN x"; var result = statementRunner.Run(statement, parameters); var node = (INode)result.Single().As <IRecord>()["x"]; var nodeCounter = i.HasValue && i.Value > 1 ? $"({i})" : string.Empty; Console.WriteLine($"{string.Join(",", node.Labels)} node created with Id={node.Id} and {node.Properties.Count} properties {nodeCounter}"); return(result.Summary.Counters.NodesCreated); }
/// <summary> /// Add relation between nodes. /// </summary> /// <typeparam name="T">Type used for relation record</typeparam> /// <param name="statementRunner">Either a session or a transation to execute the statement</param> /// <param name="relation">Object used as relation specifier</param> /// <param name="mappingConfig">Description on how to interpret record object</param> /// <param name="i">Optional counter if used from collection. Only used for logging.</param> public static int AddRelation <T>(this IStatementRunner statementRunner, T relation, MappingConfig mappingConfig, int?i = null) { // MATCH (f:FromNodeType), (t:ToNodeType) // WHERE f.FromPropertyName = 'FromPropertyValue' AND t.ToPropertyName = 'ToPropertyValue' // CREATE (f)-[r:RELATIONTYPE]->(t) // RETURN r var parameters = relation.GetProperties(); var fromPropertyName = nameof(IRelation.FromId).ToCamelCase(); var toPropertyName = nameof(IRelation.ToId).ToCamelCase(); var fromPropertyValue = parameters[fromPropertyName]; var toPropertyValue = parameters[toPropertyName]; var properties = parameters.Where(p => p.Key != fromPropertyName && p.Key != toPropertyName).ToDictionary(p => p.Key, p => p.Value); var valuePairs = string.Join(", ", properties.Select(p => $"{p.Key}: {{{p.Key}}}")); var statement = $"MATCH (f:{mappingConfig.FromNode}), (t:{mappingConfig.ToNode}) WHERE f.{mappingConfig.FromProperty}={fromPropertyValue} AND t.{mappingConfig.ToProperty}={toPropertyValue} CREATE (f)-[r:{mappingConfig.RelationName} {{{valuePairs}}}]->(t) RETURN r"; var result = statementRunner.Run(statement, properties); var relationship = (IRelationship)result.Single().As <IRecord>()["r"]; var relationCounter = i.HasValue ? $"({i})" : string.Empty; Console.WriteLine($"{relationship.Type} relation created with Id={relationship.Id} and {relationship.Properties.Count} properties {relationCounter}"); return(result.Summary.Counters.RelationshipsCreated); }
public static IResultSummary Execute(this IStatementRunner ext, string query, object param = null) { ext = ext ?? throw new ArgumentNullException(nameof(ext)); return(ext.Run(GetStatement(query, param, ext))?.Summary); }
internal static object Execute <TResult>(IStatementRunner runner, Statement statement, Func <IRecord, Type, object> mapper, Expression expression) { bool IsEnumerable = typeof(TResult).IsEnumerable(); Type typeResult; QueryTranslator tranaslator = new QueryTranslator(); expression = Evaluator.PartialEval(expression); string statementText = Regex.Replace(statement.Text, "RETURN", "WITH", RegexOptions.IgnoreCase); PipeVariableRewriter rewriter = new PipeVariableRewriter(); statementText = rewriter.Tokenize(statementText).Rebuild(); (string firstVar, IEnumerable <string> otherVars) = GetFirstCypherVariableName(statementText); string queryText = tranaslator.Translate(expression, out MethodCallExpression terminal, out int?countFromBegin, out typeResult, firstVar, otherVars); queryText = Regex.Replace($"{statementText} {queryText}", "RETURN", "WITH", RegexOptions.IgnoreCase); queryText = rewriter.Tokenize(queryText).Rebuild(); queryText = Regex.Replace(queryText, "WITH(.+?)$", "RETURN$1", RegexOptions.IgnoreCase | RegexOptions.RightToLeft); IStatementResult result = runner.Run(queryText, statement.Parameters); IQueryable <IRecord> records = result.ToList().AsQueryable(); if (terminal != null) { IRecord r = records.FirstOrDefault(); if (terminal.Method.Name.StartsWith("First")) { if (r == null) { if (terminal.Method.Name.EndsWith("Default")) { return(typeResult.GetDefault()); } else { throw new ArgumentOutOfRangeException(nameof(records), "The collection is empty"); } } return(mapper(r, typeResult)); } else { return(Convert.ChangeType(r.Values[r.Keys[0]], terminal.Type));//can only be an aggregate numeric value } } else { System.Collections.IList lst = (System.Collections.IList) typeof(List <>).MakeGenericType(typeResult).GetInstanceOf(null); foreach (object item in records.Select(p => mapper(p, typeResult))) { lst.Add(item); } IQueryable lstQ = lst.AsQueryable(); if (countFromBegin == null) { return(lstQ); } else { ExpressionInitialModifier treeCopier = new ExpressionInitialModifier(lstQ, countFromBegin.Value); Expression newExpressionTree = treeCopier.Visit(expression); // This step creates an IQueryable that executes by replacing Queryable methods with Enumerable methods. if (IsEnumerable) { return(lstQ.Provider.CreateQuery(newExpressionTree)); } else { return(lstQ.Provider.Execute(newExpressionTree)); } } } }