Class: FilesystemEnv::GlueEnv
- Inherits:
-
Object
- Object
- FilesystemEnv::GlueEnv
- Includes:
- FilesystemViews
- Defined in:
- lib/glue_envs/filesystem_glue_env.rb
Constant Summary collapse
- PersistLayerKey =
is the full path including node_key transform
:node_path
- VersionKey =
see mysql_glue_env to decouple persistent layer key from node key
:_rev
- NamespaceKey =
to have timestamp
:files_namespace
- MoabDataStoreDir =
FileSystemMetadataKeys = [PersistLayerKey]
".model"
- MoabDatastoreName =
".node_data.json"
- @@log =
This class provides a generic persistence layer interface to the outside world that maps to the specific implementations of the underlying persistent layers Set Logger
TinkitLog.set(self.name, :warn)
Instance Attribute Summary collapse
-
#_files_mgr_class ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#metadata_keys ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#moab_data ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#moab_datastore_name ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#model_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#model_save_params ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#namespace_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#node_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#persist_layer_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#required_instance_keys ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#required_save_keys ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#user_datastore_location ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#user_id ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#version_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
-
#views ⇒ Object
TODO: Rather than using File class directly, should a special class be used?.
Instance Method Summary collapse
- #convert_node_value_to_file_value(node_key_value) ⇒ Object
- #destroy_bulk(list_of_native_records) ⇒ Object
- #destroy_node(model_metadata) ⇒ Object
- #find_contains(key, this_value) ⇒ Object
- #find_contains_type_helper(stored_data, this_value) ⇒ Object
- #find_equals(key, this_value) ⇒ Object
-
#find_nodes_where(key, relation, this_value) ⇒ Object
-
:equals (data in the key field matches this_value) - :contains (this_value is contained in the key field data (same as equals for non-enumerable types ).
-
-
#generate_model_key(namespace, node_key_value) ⇒ Object
namespace is used to distinguish between unique data sets (i.e., users) within the model.
- #get(id) ⇒ Object
-
#initialize(persist_env, data_model_bindings) ⇒ GlueEnv
constructor
A new instance of GlueEnv.
- #model_path(model_key_value) ⇒ Object
-
#query_all ⇒ Object
TODO move to ViewsMgr.
-
#raw_all ⇒ Object
TODO: reconcile raw_all with query_all, this is the only glue env using raw_all.
- #save(new_data) ⇒ Object
Methods included from FilesystemViews
Constructor Details
#initialize(persist_env, data_model_bindings) ⇒ GlueEnv
Returns a new instance of GlueEnv.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 167 def initialize(persist_env, data_model_bindings) #TODO: determine if class_name is needed to segment cluster data within user data #via environmental settings filesystem_env = persist_env[:env] #key_fields = persist_env[:key_fields] fs_path = filesystem_env[:path] @user_id = filesystem_env[:user_id] @cluster_name = persist_env[:name] #data_model_bindings from NodeElementOperations key_fields = data_model_bindings[:key_fields] initial_views_data = data_model_bindings[:views] @required_instance_keys = key_fields[:required_keys] #DataStructureModels::Tinkit::RequiredInstanceKeys @required_save_keys = key_fields[:required_keys] #DataStructureModels::Tinkit::RequiredSaveKeys @node_key = key_fields[:primary_key] #DataStructureModels::Tinkit::NodeKey @moab_datastore_name = MoabDatastoreName @version_key = VersionKey # @model_key = @node_key #ModelKey #Change model key to persiste layer key ... #TODO: See about not making the filesystem dependent upon the node key @persist_layer_key = PersistLayerKey @namespace_key = NamespaceKey @metadata_keys = [@persist_layer_key, @version_key, @namespace_key ] #@persist_layer_key, @namespace_key] @user_datastore_location = File.join(fs_path, @user_id, MoabDataStoreDir) @model_save_params = {:nodes_save_path => @user_datastore_location, :data_file => @moab_datastore_name, :node_key => @node_key} @_files_mgr_class = FilesystemInterface::FilesMgr @views = TinkitFileSystemViews @moab_data = {:moab_datastore_name => @moab_datastore_name} #@views_mgr = ViewsMgr.new({:data_file => @data_file_name}) FileUtils.mkdir_p(fs_path) unless File.exists?(fs_path) end |
Instance Attribute Details
#_files_mgr_class ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def _files_mgr_class @_files_mgr_class end |
#metadata_keys ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def @metadata_keys end |
#moab_data ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def moab_data @moab_data end |
#moab_datastore_name ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def moab_datastore_name @moab_datastore_name end |
#model_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def model_key @model_key end |
#model_save_params ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def model_save_params @model_save_params end |
#namespace_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def namespace_key @namespace_key end |
#node_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def node_key @node_key end |
#persist_layer_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def persist_layer_key @persist_layer_key end |
#required_instance_keys ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def required_instance_keys @required_instance_keys end |
#required_save_keys ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def required_save_keys @required_save_keys end |
#user_datastore_location ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def user_datastore_location @user_datastore_location end |
#user_id ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def user_id @user_id end |
#version_key ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def version_key @version_key end |
#views ⇒ Object
TODO: Rather than using File class directly, should a special class be used?
149 150 151 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 149 def views @views end |
Instance Method Details
#convert_node_value_to_file_value(node_key_value) ⇒ Object
389 390 391 392 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 389 def convert_node_value_to_file_value(node_key_value) file_base_value = node_key_value.to_s.gsub("::", "_") file_value = File.join(@user_datastore_location, file_base_value) end |
#destroy_bulk(list_of_native_records) ⇒ Object
377 378 379 380 381 382 383 384 385 386 387 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 377 def destroy_bulk(list_of_native_records) @@log.info {"Bulk Destroy: #{list_of_native_records.inspect}"} if @@log.info? return [] unless (list_of_native_records) list_of_native_records.each do |recs| next unless (recs && recs.size > 0)#raise "recs not hash: #{recs}" unless recs.class == Hash rec_id = recs[@persist_layer_key] || generate_model_key(nil, recs[@node_key]) #rec_id = File.join(@user_datastore_location, rec_id) if File.dirname(rec_id) == "." #puts "Removing: #{r.inspect}" FileUtils.rm_rf(rec_id) end end |
#destroy_node(model_metadata) ⇒ Object
349 350 351 352 353 354 355 356 357 358 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 349 def destroy_node() #root_dir = @user_datastore_location #model_path(model_metadata[@model_key]) node_id = [@persist_layer_key] || generate_model_key(nil, [@node_key]) node_dir = node_id #File.join(root_dir, node_id) FileUtils.rm_rf(node_dir) #node = nil end |
#find_contains(key, this_value) ⇒ Object
264 265 266 267 268 269 270 271 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 264 def find_contains(key, this_value) results =[] query_all.each do |record| test_val = record[key] results << record if find_contains_type_helper(test_val, this_value) end results end |
#find_contains_type_helper(stored_data, this_value) ⇒ Object
273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 273 def find_contains_type_helper(stored_data, this_value) #p stored_dataj resp = nil #stored_data = jparse(stored_dataj) if stored_data.respond_to?(:"include?") resp = (stored_data.include?(this_value)) else resp = (stored_data == this_value) end return resp end |
#find_equals(key, this_value) ⇒ Object
255 256 257 258 259 260 261 262 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 255 def find_equals(key, this_value) results =[] query_all.each do |record| test_val = record[key] results << record if test_val == this_value end results end |
#find_nodes_where(key, relation, this_value) ⇒ Object
-
:equals (data in the key field matches this_value)
-
:contains (this_value is contained in the key field data (same as equals for non-enumerable types )
245 246 247 248 249 250 251 252 253 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 245 def find_nodes_where(key, relation, this_value) res = case relation when :equals find_equals(key, this_value) when :contains find_contains(key, this_value) end #case return res end |
#generate_model_key(namespace, node_key_value) ⇒ Object
namespace is used to distinguish between unique data sets (i.e., users) within the model
362 363 364 365 366 367 368 369 370 371 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 362 def generate_model_key(namespace, node_key_value) #was in FileSystemEnv mixin #fs_generate_model_key(namespace, node_key) #TODO: Make sure namespace is portable across model migrations file_name = convert_node_value_to_file_value(node_key_value) #TODO: Expand bad character set #FIXME namespace is redundant so removed it #"#{namespace}/#{node_key}" file_name end |
#get(id) ⇒ Object
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 285 def get(id) return nil unless id #maybe put in some validations to ensure its from the proper collection namespace? #id may be the entry or the full path id_path = if id.include? (@user_datastore_location) id else convert_node_value_to_file_value(id) end #id_path = id #convert_node_value_to_file_value(id) data_file_path = File.join(id_path, @moab_datastore_name) rtn = if File.exists?(data_file_path) #data_file_path = File.join(id_path, @moab_datastore_name) json_data = File.open(data_file_path, 'r'){|f| f.read} node_data = JSON.parse(json_data) node_data = HashKeys.str_to_sym(node_data) else puts "Warning: File path doesn't exist: #{data_file_path.inspect}" [] end end |
#model_path(model_key_value) ⇒ Object
373 374 375 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 373 def model_path(model_key_value) #model_key_value.gsub("::","/") end |
#query_all ⇒ Object
TODO move to ViewsMgr
209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 209 def query_all #TODO move to ViewsMgr unless File.exists?(@user_datastore_location) @@log.debug {"Warning: Can't query records. The File System Directory to work from does not exist: #{@user_datastore_location}"} if @@log.debug? end all_records = [] my_dir = @user_datastore_location + '/' #TODO: Can this be removed? all_entries = Dir.working_entries(my_dir) || [] @@log.debug "querying directory: #{my_dir.inspect} and got entries: #{all_entries.inspect}" all_entries.each do|entry| all_records << get(entry) || {} end @@log.debug {"query_all returning: #{all_records.inspect}" } if @@log.debug? return all_records end |
#raw_all ⇒ Object
TODO: reconcile raw_all with query_all, this is the only glue env using raw_all
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 225 def raw_all query_all =begin @@log.debug {"Getting All (Raw) Data using "\ "data loc: #{@user_datastore_location.inspect} "\ "datastore name: #{@moab_datastore_name.inspect}" } if @@log.debug? entries = query_all raw_nodes = [] entries.each do |record| data_path = File.join(record[@persist_layer_key], @moab_datastore_name) data_json = File.open(data_path, 'r'){|f| f.read} data = JSON.parse(data_json) raw_nodes << data end raw_nodes =end end |
#save(new_data) ⇒ Object
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/glue_envs/filesystem_glue_env.rb', line 307 def save(new_data) save_data = nil if new_data[@persist_layer_key] save_data = new_data elsif new_data[@node_key] persist_key_value = convert_node_value_to_file_value(new_data[@node_key]) save_data = new_data.merge({@persist_layer_key => persist_key_value}) else raise "Save Data did not include any keys for saving, data: #{new_data.inspect}" end save_path = @user_datastore_location save_location = save_data[@persist_layer_key] @@log.debug {"Save Directory: #{save_location.inspect}"} if @@log.debug? #was in FileSystemEnv mixin #fs_save(@model_save_params, model_data) #puts "FSG save udl: #{@user_datastore_location.inspect}" #parent_path = @user_datastore_location #node_key = @model_save_params[:node_key] #node_key = @node_key #puts "parent_path: #{parent_path.inspect}" #puts "new data node key: #{new_data[node_key].inspect}" #node_path = File.join(parent_path, new_data[node_key]) file_name = File.basename(@moab_datastore_name) file_location = File.join(save_location, file_name) #error_str = "Filesystem can't handle some characters in/ #{file_location.inspect}" #raise error_str if new_data [node_key] =~ /::/ #FilesystemEnv::BADCHARS @@log.info {"File Location: #{file_location.inspect}"} if @@log.info? model_data = HashKeys.sym_to_str(save_data) FileUtils.mkdir_p(save_location) unless File.exist?(save_location) #raise "WTF?" unless File.exist?(save_location) rev = Time.now.hash #<- I would use File.mtime, but how to get the mod time before saving? model_data[@version_key] = rev f = File.open(file_location, 'w') f.write(model_data.to_json) f.close model_data['rev'] = model_data[@version_key] #TODO <-Investigate to see if it could be consistent return model_data end |