Exemple #1
0
        private static Domain.Model.QueryResult GetNeuronResults(Guid?centralGuid, Guid?relativeGuid, string settingName, NeuronQuery neuronQuery, CancellationToken token = default(CancellationToken))
        {
            Domain.Model.QueryResult result = null;

            using (var db = ArangoDatabase.CreateWithSetting(settingName))
            {
                var queryResult = db.CreateStatement <Domain.Model.NeuronResult>(
                    NeuronRepository.CreateQuery(centralGuid, relativeGuid, neuronQuery, out List <QueryParameter> queryParameters),
                    queryParameters,
                    options: new QueryOption()
                {
                    FullCount = true
                }
                    );
                var neurons = queryResult.AsEnumerable().ToArray();

                if (centralGuid.HasValue)
                {
                    neurons.ToList().ForEach(nr => nr.Terminal = nr.Terminal.CloneExcludeSynapticPrefix());
                }

                var fullCount = (int)queryResult.Statistics.Extra.Stats.FullCount;

                if (
                    neuronQuery.Page.Value != 1 &&
                    fullCount == NeuronRepository.CalculateOffset(neuronQuery.Page.Value, neuronQuery.PageSize.Value) &&
                    neurons.Length == 0
                    )
                {
                    throw new ArgumentOutOfRangeException("Specified/Default Page is invalid.");
                }

                result = new Domain.Model.QueryResult()
                {
                    Count   = fullCount,
                    Neurons = neurons
                };
            }

            return(result);
        }
Exemple #2
0
        private static string CreateQuery(Guid?centralGuid, Guid?relativeGuid, NeuronQuery neuronQuery, out List <QueryParameter> queryParameters)
        {
            queryParameters = new List <QueryParameter>();
            var queryFiltersBuilder = new StringBuilder();
            var queryStringBuilder  = new StringBuilder();

            Func <string, string> valueBuilder = s => $"%{s}%";
            Func <string, List <string>, string, string> selector = (f, ls, s) => $"Upper(n.Tag) LIKE Upper(@{f + (ls.IndexOf(s) + 1)})";

            // TagContains
            NeuronRepository.ExtractFilters(neuronQuery.TagContains, nameof(NeuronQuery.TagContains), valueBuilder, selector, queryParameters, queryFiltersBuilder, "&&");
            // TagContainsNot
            NeuronRepository.ExtractFilters(neuronQuery.TagContainsNot, nameof(NeuronQuery.TagContainsNot), valueBuilder, selector, queryParameters, queryFiltersBuilder, "||", "NOT");

            valueBuilder = s => $"Neuron/{s}";
            selector     = (f, ls, s) => $"n._id == @{f + (ls.IndexOf(s) + 1)}";
            // IdEquals
            NeuronRepository.ExtractFilters(neuronQuery.Id, nameof(NeuronQuery.Id), valueBuilder, selector, queryParameters, queryFiltersBuilder, "||");
            // IdEqualsNot
            NeuronRepository.ExtractFilters(neuronQuery.IdNot, nameof(NeuronQuery.IdNot), valueBuilder, selector, queryParameters, queryFiltersBuilder, "||", "NOT");

            valueBuilder = s => s;
            selector     = (f, ls, s) => $"n.RegionId == @{f + (ls.IndexOf(s) + 1)}";
            // RegionIdEquals
            NeuronRepository.ExtractFilters(neuronQuery.RegionId, nameof(NeuronQuery.RegionId), valueBuilder, selector, queryParameters, queryFiltersBuilder, "||");
            // RegionIdEqualsNot
            NeuronRepository.ExtractFilters(neuronQuery.RegionIdNot, nameof(NeuronQuery.RegionIdNot), valueBuilder, selector, queryParameters, queryFiltersBuilder, "||", "NOT");

            var neuronAuthorRegion       = @"
                        LET neuronCreationAuthorTag = (
                            FOR neuronAuthorNeuron in Neuron
                            FILTER neuronAuthorNeuron._id == CONCAT(""Neuron/"", n.CreationAuthorId)
                            return neuronAuthorNeuron.Tag
                        )
                        LET neuronLastModificationAuthorTag = (
                            FOR neuronAuthorNeuron in Neuron
                            FILTER neuronAuthorNeuron._id == CONCAT(""Neuron/"", n.LastModificationAuthorId)
                            return neuronAuthorNeuron.Tag
                        )
                        LET neuronUnifiedLastModificationAuthorTag = (
                            FOR neuronAuthorNeuron in Neuron
                            FILTER neuronAuthorNeuron._id == CONCAT(""Neuron/"", n.UnifiedLastModificationAuthorId)
                            return neuronAuthorNeuron.Tag
                        )
                        LET neuronRegionTag = (
                            FOR regionNeuron in Neuron
                            FILTER regionNeuron._id == CONCAT(""Neuron/"", n.RegionId)
                            return regionNeuron.Tag
                        )";
            var neuronAuthorRegionReturn = ", NeuronCreationAuthorTag: FIRST(neuronCreationAuthorTag), NeuronLastModificationAuthorTag: FIRST(neuronLastModificationAuthorTag), NeuronUnifiedLastModificationAuthorTag: FIRST(neuronUnifiedLastModificationAuthorTag), NeuronRegionTag: FIRST(neuronRegionTag)";

            if (!centralGuid.HasValue)
            {
                // Neuron Active
                NeuronRepository.AddActiveFilter("n", neuronQuery.NeuronActiveValues.Value, queryFiltersBuilder);

                queryStringBuilder.Append($@"
                    FOR n IN Neuron
                        {queryFiltersBuilder}
                        {neuronAuthorRegion}
                            RETURN {{ Neuron: n, Terminal: {{}}{neuronAuthorRegionReturn} }}");
            }
            else
            {
                // Terminal Active
                NeuronRepository.AddActiveFilter("t", neuronQuery.TerminalActiveValues.Value, queryFiltersBuilder);

                string letPre    = string.Empty,
                       inPre     = string.Empty,
                       filterPre = string.Empty;

                string activeSynapticTemplate = string.Empty;
                if (Helper.TryConvert(neuronQuery.NeuronActiveValues.Value, out bool active))
                {
                    activeSynapticTemplate = " && {0}.Active == " + active.ToString();
                }

                if (neuronQuery.RelativeValues.Value.HasFlag(RelativeValues.Presynaptic))
                {
                    // get all presynaptic neurons of current terminal
                    letPre = $@"LET presynaptics = (
                            FOR presynaptic IN Neuron
                            FILTER presynaptic._id == t._from{string.Format(activeSynapticTemplate, "presynaptic")}
                            return presynaptic
                        )";
                    // where "to" is centralGuid
                    inPre     = $@"t._to == @{nameof(centralGuid)} && LENGTH(presynaptics) > 0 ?
                                    presynaptics :";
                    filterPre = $@"t._to == @{nameof(centralGuid)}";

                    if (relativeGuid.HasValue)
                    {
                        filterPre += $@" && t._from == @{nameof(relativeGuid)}";
                    }
                }

                string letPost    = string.Empty,
                       inPost     = string.Empty,
                       filterPost = string.Empty;

                if (neuronQuery.RelativeValues.Value.HasFlag(RelativeValues.Postsynaptic))
                {
                    // get postsynaptic neurons
                    letPost    = $@"LET postsynaptics = (
                            FOR postsynaptic IN Neuron
                            FILTER postsynaptic._id == t._to{string.Format(activeSynapticTemplate, "postsynaptic")}
                            return postsynaptic
                        )";
                    inPost     = $@"t._from == @{nameof(centralGuid)} && LENGTH(postsynaptics) > 0 ? 
                                postsynaptics :";
                    filterPost = $@"t._from == @{nameof(centralGuid)}";

                    if (relativeGuid.HasValue)
                    {
                        filterPost += $@" && t._to == @{nameof(relativeGuid)}";
                    }
                }

                queryStringBuilder.Append($@"
                    FOR t in Terminal 
                        {letPost}
                        {letPre}
                        FOR n IN (
                            {inPost}
                                {inPre}
                                    [ {{ }} ]
                            )
                        LET terminalCreationAuthorTag = (
                            FOR terminalAuthorNeuron in Neuron
                            FILTER terminalAuthorNeuron._id == CONCAT(""Neuron/"", t.CreationAuthorId)
                            return terminalAuthorNeuron.Tag
                        )
                        LET terminalLastModificationAuthorTag = (
                            FOR terminalAuthorNeuron in Neuron
                            FILTER terminalAuthorNeuron._id == CONCAT(""Neuron/"", t.LastModificationAuthorId)
                            return terminalAuthorNeuron.Tag
                        )
                        {neuronAuthorRegion}
                        FILTER {filterPost} {(!string.IsNullOrEmpty(filterPost) && !string.IsNullOrEmpty(filterPre) ? "||" : string.Empty)} {filterPre}
                        {queryFiltersBuilder}
                            RETURN {{ Neuron: n, Terminal: t, TerminalCreationAuthorTag: FIRST(terminalCreationAuthorTag), TerminalLastModificationAuthorTag: FIRST(terminalLastModificationAuthorTag){neuronAuthorRegionReturn}}}");

                queryParameters.Add(new QueryParameter()
                {
                    Name  = nameof(centralGuid),
                    Value = $"Neuron/{centralGuid.Value.ToString()}"
                });

                if (relativeGuid.HasValue)
                {
                    queryParameters.Add(new QueryParameter()
                    {
                        Name  = nameof(relativeGuid),
                        Value = $"Neuron/{relativeGuid.Value.ToString()}"
                    });
                }
            }

            var preSynapticParamCount = queryParameters.Count;

            // Postsynaptic
            NeuronRepository.ApplySynapticFilters(neuronQuery.Postsynaptic, nameof(NeuronQuery.Postsynaptic), queryParameters, queryStringBuilder);

            // PostsynapticNot
            NeuronRepository.ApplySynapticFilters(neuronQuery.PostsynapticNot, nameof(NeuronQuery.PostsynapticNot), queryParameters, queryStringBuilder, false);

            // Presynaptic
            NeuronRepository.ApplySynapticFilters(neuronQuery.Presynaptic, nameof(NeuronQuery.Presynaptic), queryParameters, queryStringBuilder);

            // PresynapticNot
            NeuronRepository.ApplySynapticFilters(neuronQuery.PresynapticNot, nameof(NeuronQuery.PresynapticNot), queryParameters, queryStringBuilder, false);

            // Sort and Limit
            var lastReturnIndex = queryStringBuilder.ToString().ToUpper().LastIndexOf("RETURN");

            queryStringBuilder.Remove(lastReturnIndex, 6);

            // were synaptic filters applied?
            bool   synapticFiltersApplied = preSynapticParamCount < queryParameters.Count;
            string sortFieldName          = synapticFiltersApplied ? "n.Neuron.Tag" : "n.Tag";
            string sortOrder = neuronQuery.SortOrder.HasValue ?
                               neuronQuery.SortOrder.Value.ToEnumString() :
                               "ASC";

            if (neuronQuery.SortBy.HasValue)
            {
                sortFieldName = neuronQuery.SortBy.Value.ToEnumString();

                if (synapticFiltersApplied)
                {
                    sortFieldName = "n." + sortFieldName;
                }
                else
                {
                    if (sortFieldName.StartsWith("Neuron."))
                    {
                        sortFieldName = sortFieldName.Replace("Neuron.", "n.");
                    }
                    else if (sortFieldName.StartsWith("Terminal."))
                    {
                        sortFieldName = sortFieldName.Replace("Terminal.", "t.");
                    }
                    else
                    {
                        sortFieldName = sortFieldName[0].ToString().ToLower() + sortFieldName.Substring(1);
                    }
                }
            }

            queryStringBuilder.Insert(lastReturnIndex, $"SORT {sortFieldName} {sortOrder} LIMIT @offset, @count RETURN");
            queryParameters.Add(new QueryParameter()
            {
                Name = "offset", Value = NeuronRepository.CalculateOffset(neuronQuery.Page.Value, neuronQuery.PageSize.Value)
            });
            queryParameters.Add(new QueryParameter()
            {
                Name = "count", Value = neuronQuery.PageSize.Value
            });

            return(queryStringBuilder.ToString());
        }