Class: Vagrant::DataStore

Inherits:
Util::HashWithIndifferentAccess show all
Defined in:
lib/vagrant/data_store.rb

Overview

The Vagrant data store is a key-value store which is persisted as JSON in a local file which is specified in the initializer. The data store itself is accessed via typical hash accessors: [] and []=. If a key is set to nil, then it is removed from the datastore. The data store is only updated on disk when #commit is called on the data store itself.

The data store is a hash with indifferent access, meaning that while all keys are persisted as strings in the JSON, you can access them back as either symbols or strings. Note that this is only true for the top-level data store. As soon as you set a hash inside the data store, unless you explicitly use a Util::HashWithIndifferentAccess, it will be a regular hash.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Util::HashWithIndifferentAccess

#[], #[]=, #delete, #key?, #merge, #merge!, #values_at

Constructor Details

#initialize(file_path) ⇒ DataStore

Returns a new instance of DataStore.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/vagrant/data_store.rb', line 22

def initialize(file_path)
  @logger    = Log4r::Logger.new("vagrant::datastore")

  if file_path
    @logger.info("Created: #{file_path}")

    @file_path = Pathname.new(file_path)
    if @file_path.exist?
      raise Errors::DotfileIsDirectory if @file_path.directory?

      begin
        merge!(JSON.parse(@file_path.read))
      rescue JSON::ParserError
        # Ignore if the data is invalid in the file.
        @logger.error("Data store contained invalid JSON. Ignoring.")
      end
    end
  else
    @logger.info("No file path. In-memory data store.")
    @file_path = nil
  end
end

Instance Attribute Details

#file_pathObject (readonly)

Returns the value of attribute file_path.



20
21
22
# File 'lib/vagrant/data_store.rb', line 20

def file_path
  @file_path
end

Instance Method Details

#commitObject

Commits any changes to the data to disk. Even if the data hasn't changed, it will be reserialized and written to disk.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/vagrant/data_store.rb', line 47

def commit
  if !@file_path
    raise StandardError, "In-memory data stores can't be committed."
  end

  clean_nil_and_empties

  if empty?
    # Delete the file since an empty data store is not useful
    @logger.info("Deleting data store since we're empty: #{@file_path}")
    @file_path.delete if @file_path.exist?
  else
    @logger.info("Committing data to data store: #{@file_path}")

    @file_path.open("w") do |f|
      f.write(to_json)
      f.fsync
    end
  end
end