class GxG::Storage::FileSpace
Public Class Methods
new()
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 6 def initialize() @thread_safety = ::Mutex.new @mounted = [] end
Public Instance Methods
copy(source_path=nil,destination_path=nil, options={})
click to toggle source
Copying support:
# File lib/gxg/gxg_dbfs.rb, line 483 def copy(source_path=nil,destination_path=nil, options={}) # Four scenarios: FS_to_FS, DB_to_DB, FS_to_DB, DB_to_FS # Objective: handle both file/object and directory/persisted_array in one method! # Does OVERWRITE copy onto existing files/folders of same name. result = false error = false if source_path == destination_path error = true end # source = {:enclosure => nil, :profile => nil, :record => nil, :permissions => nil} if self.valid_path?(source_path.to_s) if source_path.to_s == "/" source[:record] = nil else source[:record] = self.volume_of_path(source_path.to_s) end if source[:record] source[:profile] = self.profile(source_path,options.merge({:follow_symlinks => true})) source[:enclosure] = self.profile(File.dirname(source_path),options.merge({:follow_symlinks => true})) source[:permissions] = self.get_permissions(source_path) else error = true log_error({:error => Exception.new("You do not have sufficient priviledges."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end else error = true log_error({:error => Exception.new("Invalid source path"), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end # Note: if destination is not full path, but path to its future enclosure, append the filename to fully qualify the destination_path if File.basename(source_path) != File.basename(destination_path) destination_path = File.expand_path(destination_path + "/" + File.basename(source_path)) end # destination = {:enclosure => self.profile(File.dirname(destination_path),options.merge({:follow_symlinks => true})), :profile => nil, :record => nil, :permissions => source[:permissions].clone} if self.valid_path?(destination_path.to_s) if destination_path.to_s == "/" destination[:record] = nil else destination[:record] = self.volume_of_path(destination_path.to_s) end if destination[:record] destination[:profile] = self.profile(destination_path,options.merge({:follow_symlinks => true})) else error = true log_error({:error => Exception.new("You do not have sufficient permissions."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end else if destination[:enclosure].is_a?(::Hash) unless destination[:enclosure][:permissions][:effective][:create] == true error = true log_error({:error => Exception.new("You do not have sufficient permissions to create at destination."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end unless error == true destination[:record] = self.volume_of_path(File.dirname(destination_path)) if destination[:record].is_a?(::Hash) # Note: this won't exist yet, but is here for future reference. destination[:record][:subpath] = (destination[:record][:subpath] + "/" + File.basename(destination_path)) end end else error = true log_error({:error => Exception.new("Invalid destination path"), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end end unless error == true if source[:profile] # determine permissions if source[:profile][:permissions][:effective][:read] == true # Does destination already exist? --> overwrite permissions? if destination[:profile] unless destination[:profile][:permissions][:effective][:write] == true error = true log_error({:error => Exception.new("You do not have sufficient permissions at destination."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end end unless error == true # determine copying scenario: FS_to_FS, DB_to_DB, FS_to_DB, DB_to_FS if source[:record][:volume].file_system?() if destination[:enclosure][:uuid].to_s.size > 0 scenario = :FS_to_DB else scenario = :FS_to_FS end else if destination[:enclosure][:uuid].to_s.size > 0 scenario = :DB_to_DB else scenario = :DB_to_FS end end # create source/destination path pairings: file_list = [] dir_list = [] if ["persisted_array","directory","virtual_directory"].include?(source[:profile][:type].to_s) # directory / collection search_queue = [{:source => (source_path), :destination => (destination_path)}] while search_queue.size > 0 do entry = search_queue.shift if entry self.entries(entry[:source]).each do |the_profile| new_record = {:source => (entry[:source] + "/" + the_profile[:title]), :destination => (entry[:destination] + "/" + the_profile[:title]), :mode => the_profile[:mode], :mime => the_profile[:mime]} if ["persisted_array","directory","virtual_directory"].include?(the_profile[:type].to_s) dir_list << new_record search_queue << new_record else file_list << new_record end end end end else # single object file_list << {:source => (source_path), :destination => (destination_path)} end # lay down dir structure dir_list.each do |the_record| self.mkpath(the_record[:destination]) end # case scenario when :FS_to_FS # copy files one at a time. file_list.each do |the_record| if self.exist?(the_record[:destination]) self.rmfile(the_record[:destination]) end # FIXME: find a way to preserve :mode (via REAL FS path) on new file. begin source_file = self.open(the_record[:source]) destination_file = self.mkfile(the_record[:destination]) if source_file && destination_file GxG::apportioned_ranges(source_file.size,65536).each do |the_range| source_file.seek(the_range.first) destination_file.write(GxG::ByteArray.new(source_file.read(the_range.size)).to_s) end destination_file.close source_file.close else raise Exception, "Error opening source or destination files." end rescue Exception => the_error log_error({:error => the_error, :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) error = true break end end unless error == true destination[:permissions].each do |the_entry| self.set_permissions(destination_path, the_entry[:credential], the_entry[:permissions]) end result = true end when :FS_to_DB file_list.each do |the_record| begin # Question: should I support an object import format from a text file ?? if File.extname(the_record[:source]) == ".gxg_export" && (the_record[:mime] == "application/octet-stream" || the_record[:mime] == "application/json") source_file = self.open(the_record[:source]) # import_record = source_file.read() source_file.close if import_record.to_s.json? import_record = ::JSON::parse(import_record,{:symbolize_names => true}) end if import_record.is_a?(::Hash) database = nil if destination[:record].is_a?(::Hash) if destination[:record][:volume].is_a?(GxG::Storage::Volume) database = destination[:record][:volume].database() end end if database enclosure_uuid = self.profile(File.dirname(the_record[:destination]))[:uuid].to_s.to_sym destination_uuid = import_record[:record][:uuid].to_s.to_sym # Import Formats first if import_record[:formats].is_a?(::Hash) op_frame = {:operation => :merge_format, :data => []} import_record[:formats].keys.each do |the_format_key| op_frame[:data] << import_record[:formats][(the_format_key)] end if op_frame[:data].size > 0 database.synchronize_records([(op_frame)],destination[:record][:volume].credential()) end end # database.synchronize_records([{:operation => :merge, :data => [(import_record[:record])]}],destination[:record][:volume].credential()) # unless self.exist?(the_record[:destination]) the_enclosure = database.retrieve_by_uuid(enclosure_uuid, destination[:record][:volume].credential()) the_enclosure.wait_for_reservation destination_object = database.retrieve_by_uuid(destination_uuid, destination[:record][:volume].credential()) the_enclosure << destination_object destination_object.deactivate the_enclosure.release_reservation the_enclosure.deactivate end # else raise Exception, "Error aquiring destination database." end else raise Exception, "Error importing source file." end else # Import the FS file into the DB as a org.gxg.file object source_file = self.open(the_record[:source]) destination_object = self.open(the_record[:destination],{:format => "org.gxg.file"}) if source_file && destination_object destination_object.wait_for_reservation destination_object[:mime] = the_record[:mime] if destination_object[:file_segments].size > 0 (0..(destination_object[:file_segments].size - 1)).to_a.reverse.each do |the_segment_index| destination_object[:file_segments].delete_at(the_segment_index).destroy end end GxG::apportioned_ranges(source_file.size,65536).each do |the_range| source_file.seek(the_range.first) destination_object[:file_segments] << GxG::ByteArray.new(source_file.read(the_range.size)) destination_object[:file_segments].save destination_object[:file_segments].unload(destination_object[:file_segments].size - 1) end destination_object.release_reservation destination_object.deactivate source_file.close else if source_file source_file.close raise Exception, "Error opening destination object." else raise Exception, "Error opening source file & destination object." end end end rescue Exception => the_error log_error({:error => the_error, :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) error = true break end end unless error == true destination[:permissions].each do |the_entry| self.set_permissions(destination_path, the_entry[:credential], the_entry[:permissions]) end result = true end when :DB_to_FS file_list.each do |the_record| begin # Unless the object format is org.gxg.file --> export as .gxg_export object (formats + record) source_object = self.open(the_record[:source]) database = source_object.db_address[:database] # check if it is an org.gxg.file for export current_format = nil if source_object.format().to_s.size > 0 the_format = database.format_load({:uuid => source_object.format().to_s.to_sym}) if the_format[:ufs].to_s == "org.gxg.file" current_format = the_format[:ufs].to_s end end if current_format.to_s == "org.gxg.file" destination_file = self.open(the_record[:destination]) source_object[:file_segments].each_with_index do |the_segment, segment_index| destination_file.write(the_segment.to_s) source_object[:file_segments].unload(segment_index) # Field no longer exists: the_segment.unload end source_object.release_reservation source_object.deactivate destination_file.close else # Review: replace with <db>.sync_export(<uuid-array>).to_json format_records = {} object_record = source_object.export object_record.search do |item,selector,container| if selector == :format || selector == :constraint if item.to_s.size > 0 format_uuid = item unless format_records[(item.to_s.to_sym)].is_a?(::Hash) format_sample = database.format_load({:uuid => format_uuid.to_s.to_sym}) format_sample[:content] = format_sample[:content].gxg_export() format_records[(format_uuid.to_s.to_sym)] = format_sample end end end end buffer = GxG::ByteArray.new({:formats => format_records, :record => object_record}.to_json) # unless File.extname(the_record[:destination]) == ".gxg_export" the_record[:destination] = (File.dirname(the_record[:destination]) + "/" + File.basename(the_record[:destination]) + ".gxg_export") end if self.exist?(the_record[:destination]) self.rmfile(the_record[:destination]) end destination_file = self.open(the_record[:destination]) destination_file.write(buffer.to_s) destination_file.close end # rescue Exception => the_error log_error({:error => the_error, :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) error = true break end end unless error == true destination[:permissions].each do |the_entry| self.set_permissions(destination_path, the_entry[:credential], the_entry[:permissions]) end result = true end when :DB_to_DB source_database = source[:record][:volume].database() destination_database = destination[:record][:volume].database() if source_database && destination_database file_list.each do |the_record| source_object = self.open(the_record[:source]) current_format = nil if source_object.format().to_s.size > 0 the_format = source_database.format_load({:uuid => source_object.format().to_s.to_sym}) if the_format[:ufs].to_s == "org.gxg.file" current_format = the_format[:ufs].to_s end end # if source_database == destination_database if current_format.to_s == "org.gxg.file" import_record = {:formats => {}, :record => source_object.export({:clone => true, :exclude_file_segments => true})} else import_record = {:formats => {}, :record => source_object.export({:clone => true})} end else if current_format.to_s == "org.gxg.file" import_record = {:formats => {}, :record => source_object.export({:exclude_file_segments => true})} else import_record = {:formats => {}, :record => source_object.export()} end end # Gather format records for the object. import_record.search do |item,selector,container| if selector == :format || selector == :constraint if item.to_s.size > 0 format_uuid = item unless format_records[(item.to_s.to_sym)].is_a?(::Hash) format_sample = source_database.format_load({:uuid => format_uuid.to_s.to_sym}) format_sample[:content] = format_sample[:content].gxg_export() format_records[(format_uuid.to_s.to_sym)] = format_sample end end end end # enclosure_uuid = self.profile(File.dirname(the_record[:destination]))[:uuid].to_s.to_sym destination_uuid = import_record[:record][:uuid].to_s.to_sym if source_database != destination_database # Import Formats first if import_record[:formats].is_a?(::Hash) op_frame = {:operation => :merge_format, :data => []} import_record[:formats].keys.each do |the_format_key| op_frame[:data] << import_record[:formats][(the_format_key)] end if op_frame[:data].size > 0 destination_database.synchronize_records([(op_frame)],destination[:record][:volume].credential()) end end # end # if self.exist?(the_record[:destination]) # Why? Because an object of the same NAME, but differing format/content may be present (unacceptable) self.rmfile(the_record[:destination]) # Risky, but avoids situation where: diff.db, same.uuid, gets deleted, then imported to deleted object (doh!) destination_database.empty_trash end # destination_database.synchronize_records([{:operation => :merge, :data => [(import_record[:record])]}],destination[:record][:volume].credential()) # unless self.exist?(the_record[:destination]) the_enclosure = destination_database.retrieve_by_uuid(enclosure_uuid, destination[:record][:volume].credential()) the_enclosure.wait_for_reservation destination_object = destination_database.retrieve_by_uuid(destination_uuid, destination[:record][:volume].credential()) if current_format.to_s == "org.gxg.file" # copy file segments destination_object.wait_for_reservation source_object[:file_segments].each_with_index do |the_segment, segment_index| destination_object[:file_segments] << ByteArray.new(the_segment.to_s) destination_object[:file_segments].save destination_object[:file_segments].unload(destination_object[:file_segments].size - 1) # destination_object[:file_segments][(destination_object[:file_segments].size - 1)].save # destination_object[:file_segments][(destination_object[:file_segments].size - 1)].unload source_object[:file_segments].unload(segment_index) # Field no longer exists : the_segment.unload end destination_object.release_reservation end the_enclosure << destination_object destination_object.deactivate the_enclosure.release_reservation the_enclosure.deactivate end # end unless error == true destination[:permissions].each do |the_entry| self.set_permissions(destination_path, the_entry[:credential], the_entry[:permissions]) end result = true end else log_error({:error => Exception.new("Error aquiring source or destination database."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) error = true end end # end else error = true log_error({:error => Exception.new("You do not have sufficient permissions."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end end end result end
entries(the_path="", as_credential=nil)
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 191 def entries(the_path="", as_credential=nil) result = [] if self.valid_path?(the_path.to_s) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end # if volume_record result = volume_record[:volume].entries(volume_record[:subpath].to_s, as_credential) @mounted.each do |volume_entry| if (volume_entry[:path].to_s).include?(the_path) && volume_entry[:path].to_s != the_path result << self.profile(volume_entry[:path].to_s) end end result = result.sort {|a,b| a[:title] <=> b[:title]} else path_table = [] @thread_safety.synchronize { @mounted.reverse.each do |volume_entry| path_entry = volume_entry[:path].to_s.split("/") unless path_table.include?(path_entry) path_table << path_entry end end } if the_path == "/" offset = 1 else offset = (the_path.to_s.split("/").size - 1) end # already = [] path_table.each do |subpath| if self.path_prefix(the_path.to_s,subpath.join("/").to_s) == the_path.to_s if subpath[(offset)].to_s.size > 0 unless already.include?(subpath[(offset)].to_s) the_profile = self.profile((the_path + "/" + subpath[(offset)].to_s).gsub("//","/"), {:with_credential => as_credential}) if the_profile the_profile[:title] = (subpath[(offset)].to_s) the_profile[:accessed] = DateTime.now result << the_profile end already << subpath[(offset)].to_s end end end end result = result.sort {|a,b| a[:title] <=> b[:title]} # end # else begin raise Exception, "Path not found: #{the_path}" rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path}}) end end result end
exist?(the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 92 def exist?(the_path="") self.valid_path?(the_path) end
get_permissions(the_path="", the_credential=nil)
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 96 def get_permissions(the_path="", the_credential=nil) result = [] if self.valid_path?(the_path.to_s) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end if volume_record result = volume_record[:volume].get_permissions(volume_record[:subpath].to_s, the_credential) end end result end
mkdir(the_path="", permissions=nil)
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 336 def mkdir(the_path="", permissions=nil) result = false if self.valid_path?(the_path.to_s) result = true else if self.valid_path?(::File::dirname(the_path.to_s)) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end if volume_record result = volume_record[:volume].mkdir(volume_record[:subpath].to_s, permissions) else begin raise Exception, "You do not have sufficient priviledges to create here. See the mount method." rescue Exception => the_error result = false log_error({:error => the_error, :parameters => {:path => the_path}}) end end else begin raise Exception, "Invalid path to new directory" rescue Exception => the_error result = false log_error({:error => the_error, :parameters => {:path => the_path}}) end end end result end
mkfile(the_path="", options={})
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 452 def mkfile(the_path="", options={}) result = nil if self.valid_path?(the_path.to_s) result = self.open(the_path,options) else if self.valid_path?(::File::dirname(the_path.to_s)) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end if volume_record result = volume_record[:volume].open(volume_record[:subpath].to_s, options) else begin raise Exception, "You do not have sufficient priviledges to create here." rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path, :options => options}}) end end else begin raise Exception, "Invalid path to new :file" rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path, :options => options}}) end end end result end
mkpath(the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 369 def mkpath(the_path="") result = false if the_path.to_s == "" the_path = "/" end if self.valid_path?(the_path.to_s) result = true else error_flag = false path_array = the_path.to_s.split("/") (0..(path_array.size - 1)).each do |indexer| temp_path = path_array[(0..(indexer))].join("/") if temp_path == "" temp_path = "/" end unless self.valid_path?(temp_path) unless self.mkdir(temp_path) error_flag = true break end end end unless error_flag result = true end end result end
mount(the_volume = nil, the_path = "")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 1019 def mount(the_volume = nil, the_path = "") # Allow for a path to be mounted over the top of another - design choice if the_volume.is_a?(::GxG::Storage::Volume) @thread_safety.synchronize { @mounted << {:volume => the_volume, :path => ::Pathname.new(the_path.to_s)} } true else @mounted end end
mounted?(the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 1029 def mounted?(the_path="") result = false @thread_safety.synchronize { @mounted.reverse.each do |entry| if entry[:path] == the_path result = true break end end } result end
move(source_path=nil, destination_path=nil, options={})
click to toggle source
Moving support
# File lib/gxg/gxg_dbfs.rb, line 907 def move(source_path=nil, destination_path=nil, options={}) result = false error = false if source_path == destination_path error = true end # source = {:enclosure => nil, :profile => nil, :record => nil} if self.valid_path?(source_path.to_s) if source_path.to_s == "/" source[:record] = nil else source[:record] = self.volume_of_path(source_path.to_s) end if source[:record] source[:profile] = self.profile(source_path,options.merge({:follow_symlinks => true})) source[:enclosure] = self.profile(File.dirname(source_path),options.merge({:follow_symlinks => true})) else error = true log_error({:error => Exception.new("You do not have sufficient priviledges."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end else error = true log_error({:error => Exception.new("Invalid source path"), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end # Note: if destination is not full path, but path to its future enclosure, append the filename to fully qualify the destination_path if File.basename(source_path) != File.basename(destination_path) destination_path = File.expand_path(destination_path + "/" + File.basename(source_path)) end # destination = {:enclosure => self.profile(File.dirname(destination_path),options.merge({:follow_symlinks => true})), :profile => nil, :record => nil} if self.valid_path?(destination_path.to_s) if destination_path.to_s == "/" destination[:record] = nil else destination[:record] = self.volume_of_path(destination_path.to_s) end if destination[:record] destination[:profile] = self.profile(destination_path,options.merge({:follow_symlinks => true})) else error = true log_error({:error => Exception.new("You do not have sufficient permissions."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end else if destination[:enclosure].is_a?(::Hash) unless destination[:enclosure][:permissions][:effective][:create] == true error = true log_error({:error => Exception.new("You do not have sufficient permissions to create at destination."), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end unless error == true destination[:record] = self.volume_of_path(File.dirname(destination_path)) if destination[:record].is_a?(::Hash) # Note: this won't exist yet, but is here for future reference. destination[:record][:subpath] = (destination[:record][:subpath] + "/" + File.basename(destination_path)) end end else error = true log_error({:error => Exception.new("Invalid destination path"), :parameters => {:source_path => source_path, :destination_path => destination_path, :options => options}}) end end # unless error == true if source[:record][:volume].file_system?() if destination[:enclosure][:uuid].to_s.size > 0 scenario = :FS_to_DB else scenario = :FS_to_FS end else if destination[:enclosure][:uuid].to_s.size > 0 scenario = :DB_to_DB else scenario = :DB_to_FS end end if scenario == :DB_to_DB && (source[:record][:volume].database() == destination[:record][:volume].database()) database = source[:record][:volume].database() source_enclosure = database.retrieve_by_uuid(source[:enclosure][:uuid].to_s.to_sym, source[:record][:volume].credential()) source_enclosure.wait_for_reservation destination_enclosure = database.retrieve_by_uuid(destination[:enclosure][:uuid].to_s.to_sym, source[:record][:volume].credential()) destination_enclosure.wait_for_reservation # source_enclosure.each_index do |the_index| if source_enclosure[(the_index)].uuid().to_s.to_sym == source[:profile][:uuid].to_s.to_sym destination_enclosure << source_enclosure.delete_at(the_index) break else source_enclosure[(the_index)].deactivate end end source_enclosure.release_reservation destination_enclosure.release_reservation source_enclosure.deactivate destination_enclosure.deactivate result = true else # copy to destination_path if self.copy(source_path, destination_path, options) == true # delete source_path object if ["directory","persisted_array"].include?(source[:profile][:type].to_s) result = self.rmdir(source_path) else result = self.rmfile(source_path) end end end end # result end
open(the_path="", options={})
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 398 def open(the_path="", options={}) result = nil if self.valid_path?(the_path.to_s) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end if volume_record result = volume_record[:volume].open(volume_record[:subpath].to_s, options) else begin raise Exception, "You do not have sufficient priviledges to open here." rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path, :options => options}}) end end else begin raise Exception, "Invalid path" rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path, :options => options}}) end end result end
path_prefix(src_path="", the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 24 def path_prefix(src_path="", the_path="") result = "" src_path.each_char do |the_char| if the_char == the_path[0] the_path = the_path[(1..-1)] result << the_char else break end end result end
profile(the_path="",params=nil)
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 142 def profile(the_path="",params=nil) result = nil if self.valid_path?(the_path.to_s) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end if volume_record if volume_record[:subpath].to_s.size > 0 if params result = volume_record[:volume].profile(volume_record[:subpath].to_s,params) else result = volume_record[:volume].profile(volume_record[:subpath].to_s) end result[:title] = (the_path.split("/").last.to_s) else # VFS if params base_profile = volume_record[:volume].profile(volume_record[:subpath].to_s,params) else base_profile = volume_record[:volume].profile(volume_record[:subpath].to_s) end if base_profile result = {:title => "", :type => :virtual_directory, :owner_type => :virtual_directory, :uuid => nil, :on_device => nil, :on_device_major => nil, :on_device_minor => nil, :is_device => nil, :is_device_major => nil, :is_device_minor => nil, :inode => nil, :flags => [:read], :hardlinks_to => 0, :user_id => nil, :group_id => nil, :size => 0, :block_size => 0, :blocks => 0, :accessed => nil, :modified => nil, :status_modified => nil, :permissions => {:effective => {:execute => true, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read=>true}}, :mode=>nil} result[:title] = (the_path.split("/").last.to_s) result[:accessed] = DateTime.now if base_profile[:permissions][:effective][:write] result[:permissions][:effective][:write] = true result[:permissions][:effective][:create] = true end end end else # VFS Other result = {:title => "", :type => :virtual_directory, :owner_type => :virtual_directory, :uuid => nil, :on_device => nil, :on_device_major => nil, :on_device_minor => nil, :is_device => nil, :is_device_major => nil, :is_device_minor => nil, :inode => nil, :flags => [:read], :hardlinks_to => 0, :user_id => nil, :group_id => nil, :size => 0, :block_size => 0, :blocks => 0, :accessed => nil, :modified => nil, :status_modified => nil, :permissions => {:effective => {:execute => true, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read=>true}}, :mode=>nil} result[:title] = (the_path.split("/").last.to_s) result[:accessed] = DateTime.now end else begin raise Exception, "Path not found: #{the_path}" rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path}}) end end result end
rename(the_path="", new_name="", options={})
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 425 def rename(the_path="", new_name="", options={}) result = false if self.valid_path?(the_path.to_s) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end if volume_record result = volume_record[:volume].rename(volume_record[:subpath].to_s, new_name, options) else begin raise Exception, "You do not have sufficient priviledges to rename here." rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path, :options => options}}) end end else begin raise Exception, "Invalid path" rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path, :options => options}}) end end result end
revoke_permissions(the_path="", the_credential=nil)
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 111 def revoke_permissions(the_path="", the_credential=nil) result = false if self.valid_path?(the_path.to_s) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end if volume_record result = volume_record[:volume].revoke_permissions(volume_record[:subpath].to_s, the_credential) end end result end
rmdir(the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 254 def rmdir(the_path="") result = false if self.valid_path?(the_path.to_s) begin if the_path.to_s == "/" raise Exception, "You do not have destroy permissions here" else volume_record = self.volume_of_path(the_path.to_s) end if volume_record the_profile = self.profile(the_path.to_s) if the_profile if the_profile[:permissions][:effective][:destroy] if [:virtual_directory, :directory, :persisted_array].include?(the_profile[:type]) result = volume_record[:volume].rmdir(volume_record[:subpath].to_s) else raise Exception, "Not a directory" end else raise Exception, "You do not have destroy permissions here. See unmount method." end else raise Exception, "Invalid path" end # else raise Exception, "Invalid path" end rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path}}) end else begin raise Exception, "Invalid path" rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path}}) end end result end
rmfile(the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 295 def rmfile(the_path="") result = false if self.valid_path?(the_path.to_s) begin if the_path.to_s == "/" raise Exception, "You do not have destroy permissions here" else volume_record = self.volume_of_path(the_path.to_s) end if volume_record the_profile = self.profile(the_path.to_s) if the_profile if the_profile[:permissions][:effective][:destroy] if [:virtual_directory, :directory, :persisted_array].include?(the_profile[:type]) raise Exception, "Not a valid :file or :persisted_hash" else result = volume_record[:volume].rmfile(volume_record[:subpath].to_s) end else raise Exception, "You do not have destroy permissions here. See unmount method." end else raise Exception, "Invalid path" end # else raise Exception, "Invalid path" end rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path}}) end else begin raise Exception, "Invalid path" rescue Exception => the_error log_error({:error => the_error, :parameters => {:path => the_path}}) end end result end
set_permissions(the_path="", the_credential=nil, the_permissions={})
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 127 def set_permissions(the_path="", the_credential=nil, the_permissions={}) result = false if self.valid_path?(the_path.to_s) if the_path.to_s == "/" volume_record = nil else volume_record = self.volume_of_path(the_path.to_s) end if volume_record result = volume_record[:volume].set_permissions(volume_record[:subpath].to_s, the_credential, the_permissions) end end result end
subpath(src_path="", the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 11 def subpath(src_path="", the_path="") if src_path == "/" the_path else src_path.each_char do |the_char| if the_char == the_path[0] the_path = the_path[(1..-1)] end end the_path end end
unmount(the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 1042 def unmount(the_path="") # Allow for a path to be mounted over the top of another - design choice result = nil @thread_safety.synchronize { if @mounted.size > 0 (0..(@mounted.size - 1)).to_a.reverse.each do |indexer| if the_path.to_s == (@mounted[(indexer)][:path].to_s) result = @mounted[(indexer)][:volume] @mounted.delete_at(indexer) break end end end } # returns the volume object for proper closing result end
valid_path?(the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 50 def valid_path?(the_path="") result = false if the_path.to_s == "/" result = true else # VFS check path_table = [] @thread_safety.synchronize { @mounted.reverse.each do |volume_entry| path_entry = volume_entry[:path].to_s.split("/") unless path_table.include?(path_entry) path_table << path_entry end end } path_array = the_path.to_s.split("/") vfs_check = false path_table.each do |entry| (0..(path_array.size - 1)).each do |indexer| if entry == (path_array[(0..(indexer))]) vfs_check = true break end end if vfs_check break end end # volume check if vfs_check volume_record = self.volume_of_path(the_path.to_s) if volume_record result = volume_record[:volume].exist?(volume_record[:subpath].to_s) else result = true end end # end result end
volume_of_path(the_path="")
click to toggle source
# File lib/gxg/gxg_dbfs.rb, line 37 def volume_of_path(the_path="") result = nil @thread_safety.synchronize { @mounted.reverse.each do |volume_entry| if self.path_prefix(volume_entry[:path].to_s,the_path.to_s) == (volume_entry[:path].to_s) result = {:volume => volume_entry[:volume], :subpath => self.subpath(volume_entry[:path].to_s, the_path.to_s) } break end end } result end