Class: Backspin::Record

Inherits:
Object
  • Object
show all
Defined in:
lib/backspin/record.rb

Constant Summary collapse

FORMAT_VERSION =
"4.1"
SUPPORTED_FORMAT_VERSIONS =
["4.0", FORMAT_VERSION].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Record

Returns a new instance of Record.



37
38
39
40
41
42
43
# File 'lib/backspin/record.rb', line 37

def initialize(path)
  @path = path
  @snapshot = nil
  @first_recorded_at = nil
  @recorded_at = nil
  @record_count = nil
end

Instance Attribute Details

#first_recorded_atObject (readonly)

Returns the value of attribute first_recorded_at.



9
10
11
# File 'lib/backspin/record.rb', line 9

def first_recorded_at
  @first_recorded_at
end

#pathObject (readonly)

Returns the value of attribute path.



9
10
11
# File 'lib/backspin/record.rb', line 9

def path
  @path
end

#record_countObject (readonly)

Returns the value of attribute record_count.



9
10
11
# File 'lib/backspin/record.rb', line 9

def record_count
  @record_count
end

#recorded_atObject (readonly)

Returns the value of attribute recorded_at.



9
10
11
# File 'lib/backspin/record.rb', line 9

def recorded_at
  @recorded_at
end

#snapshotObject (readonly)

Returns the value of attribute snapshot.



9
10
11
# File 'lib/backspin/record.rb', line 9

def snapshot
  @snapshot
end

Class Method Details

.build_record_path(name) ⇒ Object



25
26
27
28
29
30
# File 'lib/backspin/record.rb', line 25

def self.build_record_path(name)
  backspin_dir = Backspin.configuration.backspin_dir
  backspin_dir.mkpath

  File.join(backspin_dir, "#{name}.yml")
end

.create(name) ⇒ Object



32
33
34
35
# File 'lib/backspin/record.rb', line 32

def self.create(name)
  path = build_record_path(name)
  new(path)
end

.load_from_file(path) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/backspin/record.rb', line 17

def self.load_from_file(path)
  raise Backspin::RecordNotFoundError unless File.exist?(path)

  record = new(path)
  record.load_from_file
  record
end

.load_or_create(path) ⇒ Object



11
12
13
14
15
# File 'lib/backspin/record.rb', line 11

def self.load_or_create(path)
  record = new(path)
  record.load_from_file if File.exist?(path)
  record
end

Instance Method Details

#clearObject



85
86
87
88
89
90
# File 'lib/backspin/record.rb', line 85

def clear
  @snapshot = nil
  @first_recorded_at = nil
  @recorded_at = nil
  @record_count = nil
end

#empty?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/backspin/record.rb', line 81

def empty?
  @snapshot.nil?
end

#exists?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/backspin/record.rb', line 77

def exists?
  File.exist?(@path)
end

#load_from_fileObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/backspin/record.rb', line 92

def load_from_file
  data = YAML.load_file(@path.to_s)

  unless data.is_a?(Hash) && SUPPORTED_FORMAT_VERSIONS.include?(data["format_version"])
    raise RecordFormatError, "Invalid record format: expected format version #{FORMAT_VERSION}"
  end

  snapshot_data = data["snapshot"]
  unless snapshot_data.is_a?(Hash)
    raise RecordFormatError, "Invalid record format: missing snapshot"
  end

  format_version = data["format_version"]
  @recorded_at = data["recorded_at"] || snapshot_data["recorded_at"]
  if format_version == FORMAT_VERSION
    @first_recorded_at = data["first_recorded_at"]
    @record_count = data["record_count"]
  else
    # Backfill metadata for v4.0 records.
    @first_recorded_at = data["first_recorded_at"] || @recorded_at
    @record_count = data.fetch("record_count", 1)
  end
  validate_metadata!
  @snapshot = Snapshot.from_h(snapshot_data)
rescue Psych::SyntaxError => e
  raise RecordFormatError, "Invalid record format: #{e.message}"
end

#reloadObject



69
70
71
72
73
74
75
# File 'lib/backspin/record.rb', line 69

def reload
  @snapshot = nil
  @first_recorded_at = nil
  @recorded_at = nil
  @record_count = nil
  load_from_file if File.exist?(@path)
end

#save(filter: nil) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/backspin/record.rb', line 53

def save(filter: nil)
  FileUtils.mkdir_p(File.dirname(@path))
  snapshot_data = @snapshot&.to_h
  snapshot_data = filter.call(deep_dup(snapshot_data)) if snapshot_data && filter
  next_record_count = (@record_count || 0) + 1
  record_data = {
    "format_version" => FORMAT_VERSION,
    "first_recorded_at" => @first_recorded_at,
    "recorded_at" => @recorded_at,
    "record_count" => next_record_count,
    "snapshot" => snapshot_data
  }
  File.write(@path, record_data.to_yaml)
  @record_count = next_record_count
end

#set_snapshot(snapshot) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/backspin/record.rb', line 45

def set_snapshot(snapshot)
  @snapshot = snapshot
  snapshot_recorded_at = snapshot.recorded_at || Time.now.utc.iso8601
  @first_recorded_at ||= snapshot_recorded_at
  @recorded_at = snapshot_recorded_at
  self
end