Class: SafeDb::DataMap

Inherits:
Object
  • Object
show all
Defined in:
lib/utils/store/datamap.rb

Overview

DataMap is a key-value store backed by a plain-text file in an INI format that sits on an accessible file-system.

Example Data Exchange

Issue the below ruby calls and specify a /path/to/file

datamap = DataMap.new ( "/path/to/file" )

datamap.use ( "phone_numbers"           )
datamap.set ( "joe", "0044 7500 123456" )
datamap.set ( "amy", "0044 7678 123456" )

Now visit the file to see your exchanged data.

[phone_numbers]
joe = 0044 7500 123456
amy = 0044 7678 123456

The Current Section

You can set the current section with the #use method and then subsequent read, write, or query behaviour will reference the section that you stated.

You do not need a new object to switch sections - just go ahead and use another another one.

Remember that DataMap is two-dimensional data structure so all key-value pairs are stored under the auspices of a section.

Key-Value Pair Exchanges

Representational state transfer occurs with four methods with

  • custom sections referenced through #read and #write

  • said sections transfered via ubiquitous #get and #set

The name given to the default group can be specified to the constructor. If none is provided the aptly named “default” is used.

Instance Method Summary collapse

Constructor Details

#initialize(backing_file_path) ⇒ DataMap

Initialize the key value store and auto write a time stamp that has nano-second accuracy with a key whose name is gleened from the constant KeyData::INIT_TIME_STAMP_NAME.

The path to the backing INI file is gleened from the first backing file path parameter.

Parameters:

  • backing_file_path (String)

    the expected location of the file-backed key-value store. If the folder and/or file do not exist the folder is created and then the file is created along with the time stamps.

  • the_default_group (String)

    the name of the default group. If none is presented this value will default to the aptly named “default”.



67
68
69
70
# File 'lib/utils/store/datamap.rb', line 67

def initialize( backing_file_path )
  @file_path = backing_file_path
  create_dir_unless_exists()
end

Instance Method Details

#as_stringString

Fetch this one-dimensional data store as a string in INI file format.

Returns:

  • (String)

    an INI formatted string representation of this data



253
254
255
256
257
258
259
# File 'lib/utils/store/datamap.rb', line 253

def as_string()

  data_map = IniFile.new( :filename => @file_path, :encoding => 'UTF-8' )
  data_map = IniFile.load( @file_path ) if File.file? @file_path
  return data_map.to_s

end

#contains?(key_name) ⇒ Boolean

Return true if the settings configuration file contains the specified parameter key within the current section name that has been set via the #use method.

This method does not check the contents (value) of the key. Even if it is an empty string, this method returns true so long as the section exists and the key exists within that.

raise [ArgumentError]

if the configuration file does not exist or is empty
if the paramter key_name is nil, empty or contains only whitespace

Parameters:

  • key_name (String)

    does a key with this name exist within the current map section.

Returns:

  • (Boolean)

    return true if the current section exists and a key with the parameter name exists within it. return false if either the section or the key do not exist.



198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/utils/store/datamap.rb', line 198

def contains?( key_name )

  raise ArgumentError.new "No parameter key given." if key_name.nil? || key_name.strip.empty?
  raise ArgumentError.new "No file found at [ #{@file_path} ]" unless File.exists? @file_path
  the_text = File.read @file_path
  raise ArgumentError.new "This file is empty => [ #{@file_path} ]" if the_text.empty?

  the_data = IniFile.load @file_path
  return false unless the_data.has_section?( @section_to_use )
  return the_data[ @section_to_use ].has_key?( key_name )

end

#get(key_name) ⇒ String

Stash the setting directive and its value into the configuration file using the default settings group.

Parameters:

  • key_name (String)

    the name of the key whose value is to be written

Returns:

  • (String)

    return the value of the configuration directive in the default group

Raises:

  • (ArgumentError)


101
102
103
104
# File 'lib/utils/store/datamap.rb', line 101

def get( key_name )
  raise ArgumentError, "Cannot get from a Nil section name." if @section_to_use.nil?
  read( @section_to_use, key_name )
end

#has_section?(section_name) ⇒ Boolean

Return true if the settings configuration file contains the specified section name. This method ignores whatever section that may or may not have been pointed to by the use command.

Parameters:

  • section_name (String)

    does a section with this name exist within the file data structure

Returns:

  • (Boolean)

    return true if a section exists with the specified name



221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/utils/store/datamap.rb', line 221

def has_section?( section_name )

  KeyError.not_new( section_name, self )

  raise ArgumentError.new "No file found at [ #{@file_path} ]" unless File.exists? @file_path
  the_text = File.read @file_path
  raise ArgumentError.new "This file is empty => [ #{@file_path} ]" if the_text.empty?

  the_data = IniFile.load @file_path
  return the_data.has_section?( section_name )

end

#read(section_name, key_name) ⇒ String

Given the configuration key name and the context name, get the corresponding key value from the configuration file whose path is acquired using the SafeDb::DataMap.selfself#get_filepath method.

Parameters:

  • key_name (String)

    the key whose value is to be retrieved

Returns:

  • (String)

    the value configured for the parameter key

Raises:

  • ArgumentError for any one of a long list of reasons that cause the key value to not be retrieved. This can range from non-existent directories and files, non readable files, incorrect configurations right down to missing keys or even missing values.



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/utils/store/datamap.rb', line 156

def read( section_name, key_name )

  raise ArgumentError.new "No section given." if section_name.nil? || section_name.strip.empty?
  raise ArgumentError.new "No parameter key given." if key_name.nil? || key_name.strip.empty?
  raise ArgumentError.new "No file found at [ #{@file_path} ]" unless File.exists? @file_path
  the_text = File.read @file_path
  raise ArgumentError.new "This file is empty => [ #{@file_path} ]" if the_text.empty?

  the_data = IniFile.load @file_path
  key_exists = the_data[ section_name ].has_key?( key_name )
  key_err_msg = "Key [#{key_name}] not found in section [#{section_name}]"
  raise ArgumentError, key_err_msg unless key_exists

  rawvalue = the_data[section_name][key_name]
  key_val_msg = "Nil empty or whitespace value for key [#{section_name}][#{key_name}]"
  nil_empty_or_whitespace = rawvalue.nil? || rawvalue.chomp.strip.empty?
  raise ArgumentError, key_val_msg if nil_empty_or_whitespace

  return rawvalue.chomp.strip

end

#sectionString

Return the name of the currently in-focus section that has been set using the #use method.

Returns:

  • (String)

    return the name of the currently in-focus section

Raises:

  • (ArgumentError)


112
113
114
115
# File 'lib/utils/store/datamap.rb', line 112

def section()
  raise ArgumentError, "The use method has not specified a section." if @section_to_use.nil?
  return @section_to_use
end

#set(key_name, key_value) ⇒ Object

Stash the setting directive and its value into the configuration file using the default settings group.

Parameters:

  • key_name (String)

    the name of the key whose value is to be written

  • key_value (String)

    the data item value of the key specified

Raises:

  • (ArgumentError)


89
90
91
92
# File 'lib/utils/store/datamap.rb', line 89

def set( key_name, key_value )
  raise ArgumentError, "Cannot set a Nil section name." if @section_to_use.nil?
  write @section_to_use, key_name, key_value
end

#time_stampString

Get the time stamp that was written to the key-value store at the point it was first initialized and then subsequently written out (serialized) onto the file-system.

The time stamp returned marks the first time this key-value store was conceived by a use case actor and subsequently serialized.

Returns:

  • (String)

    the string time stamp denoting the first time this key-value store was first initialized and then subsequently written out (serialized) onto the file-system.



246
247
248
# File 'lib/utils/store/datamap.rb', line 246

def time_stamp()
  return get INIT_TIME_STAMP_NAME
end

#use(the_section_name) ⇒ Object

Set the section to use for future data exchanges via the ubiquitous #get and #set methods as well as the query contains key method.

Parameters:

  • the_section_name (String)

    the non-nil and non whitespace only section name that will lead a set of key-value pairs in the INI formatted file.

Raises:

  • (ArgumentError)


79
80
81
82
# File 'lib/utils/store/datamap.rb', line 79

def use( the_section_name )
  raise ArgumentError, "Cannot use a Nil section name." if the_section_name.nil?
  @section_to_use = the_section_name
end

#write(section_name, key, value) ⇒ Object

Write the key/value pair in the parameter into this key/value store’s backing INI file.

This method assumes the existence of the backing configuration file at the @file_path instance variable that was set during initialization.

Observable value is the written key/value pair within the specified section. The alternate flows are

  • if the section does not exist it is created

  • if the section and key exist the value is inserted or overwritten

Parameters:

  • section_name (String)

    name grouping the section of config values

  • key (String)

    the key name of config directive to be written into the file

  • value (String)

    value of the config directive to be written into the file



134
135
136
137
138
139
140
141
# File 'lib/utils/store/datamap.rb', line 134

def write( section_name, key, value )

  data_map = IniFile.new( :filename => @file_path, :encoding => 'UTF-8' )
  data_map = IniFile.load( @file_path ) if File.file? @file_path
  data_map[section_name][key] = value
  data_map.write

end