public Task Update(string keyOrId, JiraIssueFields fields)
 {
     return(InvokeByLock(() =>
     {
         var key = GetIssueStorageKey(keyOrId);
         if (!issueStorage.TryRead(key, out var issueBytes))
         {
             throw new JiraException($"issue [{keyOrId}] is not found");
         }
         var replacedIssue = JiraIssueDto.FromBytes(issueBytes);
         fields.CopyTo(replacedIssue.IssueFields);
         issueStorage.Write(key, replacedIssue.ToBytes());
         return true;
     }));
 }
        public Task <JiraIssueDto> Get(string keyOrId)
        {
            return(InvokeByLock(() =>
            {
                var key = GetIssueStorageKey(keyOrId);
                if (!issueStorage.TryRead(key, out var bytes))
                {
                    throw new JiraException($"issue '{keyOrId}' is not found");
                }
                var result = JiraIssueDto.FromBytes(bytes);
                if (issueAttachmentsIndex.TryRead(key, out var attachmentBytes))
                {
                    var attachmentIds = LongArrayFromBytes(attachmentBytes);
                    var issuesAttachments = new JiraAttachment[attachmentIds.Length];
                    for (var i = 0; i < issuesAttachments.Length; ++i)
                    {
                        if (!attachmentsHeaders.TryRead(attachmentIds[i], out var headerBytes))
                        {
                            throw new InvalidOperationException(
                                $"attachment '{attachmentIds[i]}' is not found");
                        }
                        issuesAttachments[i] =
                            Json.Deserialize <JiraAttachment>(Encoding.UTF8.GetString(headerBytes));
                    }

                    result.IssueFields.SetProperty("attachment", issuesAttachments);
                }
                else
                {
                    result.IssueFields.SetProperty("attachment", new JiraAttachment[0]);
                }

                var issueComments = ReadIssueComments(key);
                result.IssueFields.SetProperty("comment", new JiraIssueComments
                {
                    Comments = issueComments,
                    StartAt = 0,
                    Total = issueComments.Length,
                    MaxResults = issueComments.Length
                });
                return result;
            }));
        }
        public Task <JiraIssueDto[]> GetAll()
        {
            return(InvokeByLock(() =>
            {
                var allAttachments = new Dictionary <long, JiraAttachment>();
                foreach (var pair in attachmentsHeaders.ReadAll())
                {
                    allAttachments[pair.Key] =
                        Json.Deserialize <JiraAttachment>(Encoding.UTF8.GetString(pair.Value));
                }
                var attachmentsIndex = new Dictionary <long, JiraAttachment[]>();
                foreach (var pair in issueAttachmentsIndex.ReadAll())
                {
                    var attachmentIds = LongArrayFromBytes(pair.Value);
                    var issueAttachments = new JiraAttachment[attachmentIds.Length];
                    for (var i = 0; i < attachmentIds.Length; ++i)
                    {
                        issueAttachments[i] = allAttachments[attachmentIds[i]];
                    }
                    attachmentsIndex[pair.Key] = issueAttachments;
                }

                var allComments = new Dictionary <long, JiraComment>();
                foreach (var pair in commentsStorage.ReadAll())
                {
                    allComments[pair.Key] = Json.Deserialize <JiraComment>(Encoding.UTF8.GetString(pair.Value));
                }

                var commentsIndex = new Dictionary <long, JiraComment[]>();
                foreach (var pair in issueCommentsIndex.ReadAll())
                {
                    var commentIds = LongArrayFromBytes(pair.Value);
                    var issueComments = new JiraComment[commentIds.Length];
                    for (var i = 0; i < commentIds.Length; ++i)
                    {
                        issueComments[i] = allComments[commentIds[i]];
                    }
                    commentsIndex[pair.Key] = issueComments;
                }

                var issues = new List <JiraIssueDto>();
                foreach (var pair in issueStorage.ReadAll())
                {
                    var jiraIssueDto = JiraIssueDto.FromBytes(pair.Value);
                    var keyId = ExtractLong(jiraIssueDto.Key);
                    if (attachmentsIndex.TryGetValue(keyId, out var a))
                    {
                        jiraIssueDto.IssueFields.SetProperty("attachment", a);
                    }
                    else
                    {
                        jiraIssueDto.IssueFields.SetProperty("attachment", emptyAttachments);
                    }
                    if (!commentsIndex.TryGetValue(keyId, out var c))
                    {
                        c = emptyComments;
                    }
                    jiraIssueDto.IssueFields.SetProperty("comment", new JiraIssueComments
                    {
                        Comments = c,
                        StartAt = 0,
                        Total = c.Length,
                        MaxResults = c.Length
                    });
                    issues.Add(jiraIssueDto);
                }

                return issues.ToArray();
            }));
        }