Exemple #1
0
        public FluentResults.Result <(INode, bool)> Upsert(string predicate, GraphValue value, int maxRetrys = 1)
        {
            AssertNotDisposed();

            var query            = $"{{ q(func: eq({predicate}, \"{value.ToString()}\")) {{ uid }} }}";
            var newNodeBlankName = "upsertNode";

            var retryRemaining = (maxRetrys < 1) ? 1 : maxRetrys;

            FluentResults.Result <(INode, bool)> result = null;

            Func <FluentResults.Result <(INode, bool)>, FluentResults.Result <(INode, bool)>, FluentResults.Result <(INode, bool)> > addErr =
                (FluentResults.Result <(INode, bool)> curError, FluentResults.Result <(INode, bool)> newError) => {
                return(curError == null || !curError.IsFailed
                        ? newError
                        : Results.Merge <(INode, bool)>(curError, newError));
            };

            while (retryRemaining >= 0)
            {
                retryRemaining--;

                using (var txn = NewTransaction()) {
                    var queryResult = txn.Query(query);

                    if (queryResult.IsFailed)
                    {
                        result = addErr(result, queryResult.ConvertToResultWithValueType <(INode, bool)>());
                        continue;
                    }

                    if (String.Equals(queryResult.Value, "{\"q\":[]}", StringComparison.Ordinal))
                    {
                        var assigned = txn.Mutate($"{{ \"uid\": \"_:{newNodeBlankName}\", \"{predicate}\": \"{value.ToString()}\" }}");
                        if (assigned.IsFailed)
                        {
                            result = addErr(result, assigned.ConvertToResultWithValueType <(INode, bool)>());
                            continue;
                        }
                        var err = txn.Commit();
                        if (err.IsSuccess)
                        {
                            var UIDasString = assigned.Value[newNodeBlankName].Replace("0x", string.Empty); // why doesn't UInt64.TryParse() work with 0x...???
                            if (UInt64.TryParse(UIDasString, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var UID))
                            {
                                return(Results.Ok <(INode, bool)>((new UIDNode(UID), false)));
                            }
                            result = addErr(result, Results.Fail <(INode, bool)>("Failed to parse UID : " + UIDasString));
                            continue;
                        }
                        result = addErr(result, err.ConvertToResultWithValueType <(INode, bool)>());
                        continue;
                    }
                    else
                    {
                        var UIDasString = queryResult.Value
                                          .Replace("{\"q\":[{\"uid\":\"0x", string.Empty)
                                          .Replace("\"}]}", string.Empty);

                        if (UInt64.TryParse(UIDasString, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var UID))
                        {
                            return(Results.Ok <(INode, bool)>((new UIDNode(UID), true)));
                        }
                        result = addErr(result, Results.Fail <(INode, bool)>("Failed to parse UID : " + UIDasString));
                        continue;
                    }
                }
            }
            return(result);
        }