/// <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);
                    }
                }
            }
        }
Example #3
0
            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());
            }
Example #4
0
        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);
        }
Example #6
0
        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);
        }
Example #10
0
        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));
                    }
                }
            }
        }