summaryrefslogtreecommitdiff
path: root/lib/gitlab/import_export/json/ndjson_reader.rb
blob: 510da61d3ab8e987f40a8f418ad6f107dc01d7d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# frozen_string_literal: true

module Gitlab
  module ImportExport
    module Json
      class NdjsonReader
        MAX_JSON_DOCUMENT_SIZE = 50.megabytes

        attr_reader :dir_path

        def initialize(dir_path)
          @dir_path = dir_path
          @consumed_relations = Set.new
        end

        def exist?
          Dir.exist?(@dir_path)
        end

        # This can be removed once legacy_reader is deprecated.
        def legacy?
          false
        end

        def consume_attributes(importable_path)
          # This reads from `tree/project.json`
          path = file_path("#{importable_path}.json")
          data = File.read(path, MAX_JSON_DOCUMENT_SIZE)
          json_decode(data)
        end

        def consume_relation(importable_path, key, mark_as_consumed: true)
          Enumerator.new do |documents|
            next if mark_as_consumed && !@consumed_relations.add?("#{importable_path}/#{key}")

            # This reads from `tree/project/merge_requests.ndjson`
            path = file_path(importable_path, "#{key}.ndjson")

            next unless File.exist?(path)

            File.foreach(path, MAX_JSON_DOCUMENT_SIZE).with_index do |line, line_num|
              documents << [json_decode(line), line_num]
            end
          end
        end

        private

        def json_decode(string)
          Gitlab::Json.parse(string)
        rescue JSON::ParserError => e
          Gitlab::ErrorTracking.log_exception(e)
          raise Gitlab::ImportExport::Error, 'Incorrect JSON format'
        end

        def file_path(*path)
          File.join(dir_path, *path)
        end
      end
    end
  end
end