Class: SafeDb::DataStore
Overview
A Key/Value database knows how to manipulate a JSON backend data structure (put, add etc) after reading and then decrypting it from a file and before encrypting and then writing it to a file.
Difference Between DataStore and DataStore
The DataStore is a JSON backed store that streams to and from INI formatted data. The DataStore is preferred for human readable data which is precisely 2 dimensional. The streamed DataMap is JSON which at scale isn’t human readable but the data structure is N dimensional and it supports nested structures such as lists, maps, numbers and booleans.
It provides behaviour to which we can create, append (add), update (change), read parts and delete essentially two structures
-
a collection of name/value pairs
-
an ordered list of values
JSON is Not Exposed in the Interface
A key/value database doesn’t expose the data format used in the implementation allowing this to be changed seamlessly to YAMl or other formats.
Symmetric Encryption and Decryption
A key/value database supports operations to read from and write to a known filepath and with a symmetric key it can
-
decrypt after reading from a file and
-
encrypt before writing to a (the same) file
Hashes as the Primary Data Structure
The key/value database openly extends Hash as the data structure for holding
-
strings
-
arrays
-
other hashes
-
booleans
-
integers and floats
Class Method Summary collapse
-
.from_json(db_json_string) ⇒ DataStore
Return a key database data structure that is instantiated from the parameter JSON string.
Instance Method Summary collapse
-
#create_entry(dictionary_name, key_name, value) ⇒ Object
Create a new key value entry inside a dictionary with the specified name at the root of this database.
-
#create_map_entry(outer_keyname, inner_keyname, entry_keyname, entry_value) ⇒ Object
Create a new secondary tier map key value entry inside a primary tier map at the map_key_name location.
-
#delete_entry(dictionary_name, key_name) ⇒ Object
Delete an existing key value entry inside the dictionary with the specified name at the root of this database.
-
#get_entry(dictionary_name, key_name) ⇒ Object
Get the entry with the key name in a dictionary that is itself inside another dictionary (named in the first parameter) which thankfully is at the root of this database.
-
#has_entry?(dictionary_name, key_name) ⇒ Boolean
Does this database have an entry in the root dictionary named with the key_name parameter?.
-
#set(key_name, key_value) ⇒ Object
Stash the setting directive and its value into the configuration file using the default settings group.
-
#use(section) ⇒ 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.
Methods inherited from Hash
#log_contents, #merge_recursively!, #reject_message
Class Method Details
.from_json(db_json_string) ⇒ DataStore
Return a key database data structure that is instantiated from the parameter JSON string.
62 63 64 65 66 67 68 |
# File 'lib/utils/store/datastore.rb', line 62 def self.from_json( db_json_string ) data_db = DataStore.new() data_db.merge!( JSON.parse( db_json_string ) ) return data_db end |
Instance Method Details
#create_entry(dictionary_name, key_name, value) ⇒ Object
Create a new key value entry inside a dictionary with the specified name at the root of this database. Successful completion means the named dictionary will contain one more entry than it need even if it did not previously exist.
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/utils/store/datastore.rb', line 119 def create_entry( dictionary_name, key_name, value ) KeyError.not_new( dictionary_name, self ) KeyError.not_new( key_name, self ) KeyError.not_new( value, self ) self[ dictionary_name ] = {} unless self.has_key?( dictionary_name ) self[ dictionary_name ][ key_name ] = value end |
#create_map_entry(outer_keyname, inner_keyname, entry_keyname, entry_value) ⇒ Object
Create a new secondary tier map key value entry inside a primary tier map at the map_key_name location.
A failure will occur if either the outer or inner keys already exist without their values being map objects.
If this method is called against a new empty map, the resulting map structure will look like the below.
{ outer_keyname ~> { inner_keyname ~> { entry_keyname, entry_value } } }
172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/utils/store/datastore.rb', line 172 def create_map_entry( outer_keyname, inner_keyname, entry_keyname, entry_value ) KeyError.not_new( outer_keyname, self ) KeyError.not_new( inner_keyname, self ) KeyError.not_new( entry_keyname, self ) KeyError.not_new( entry_value, self ) self[ outer_keyname ] = {} unless self.has_key?( outer_keyname ) self[ outer_keyname ][ inner_keyname ] = {} unless self[ outer_keyname ].has_key?( inner_keyname ) self[ outer_keyname ][ inner_keyname ][ entry_keyname ] = entry_value end |
#delete_entry(dictionary_name, key_name) ⇒ Object
Delete an existing key value entry inside the dictionary with the specified name at the root of this database. Successful completion means the named dictionary will contain one less entry if that key existed.
251 252 253 254 255 256 257 258 |
# File 'lib/utils/store/datastore.rb', line 251 def delete_entry( dictionary_name, key_name ) KeyError.not_new( dictionary_name, self ) KeyError.not_new( key_name, self ) self[ dictionary_name ].delete( key_name ) end |
#get_entry(dictionary_name, key_name) ⇒ Object
Get the entry with the key name in a dictionary that is itself inside another dictionary (named in the first parameter) which thankfully is at the root of this database.
Only call this method if #has_entry? returns true for the same dictionary and key name parameters.
229 230 231 232 233 |
# File 'lib/utils/store/datastore.rb', line 229 def get_entry( dictionary_name, key_name ) return self[ dictionary_name ][ key_name ] end |
#has_entry?(dictionary_name, key_name) ⇒ Boolean
Does this database have an entry in the root dictionary named with the key_name parameter?
199 200 201 202 203 204 205 206 207 |
# File 'lib/utils/store/datastore.rb', line 199 def has_entry?( dictionary_name, key_name ) KeyError.not_new( dictionary_name, self ) KeyError.not_new( key_name, self ) return false unless self.has_key?( dictionary_name ) return self[ dictionary_name ].has_key?( key_name ) end |
#set(key_name, key_value) ⇒ Object
Stash the setting directive and its value into the configuration file using the default settings group.
88 89 90 91 92 93 |
# File 'lib/utils/store/datastore.rb', line 88 def set key_name, key_value raise ArgumentError, "Cannot set a Nil (section)" if @section.nil? raise ArgumentError, "Cannot set a Nil key name." if key_name.nil? raise ArgumentError, "Cannot set a Nil key value" if key_value.nil? create_entry( @section, key_name, key_value ) end |
#use(section) ⇒ 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.
77 78 79 80 |
# File 'lib/utils/store/datastore.rb', line 77 def use section raise ArgumentError, "Cannot use a Nil section." if section.nil? @section = section end |