X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Fregistry.rb;h=61d4b33e02ef454d8cebcfb52617d53bc1f9eef0;hb=8218e3f05e8ccd95497dd3c7aa115cfde8b01a40;hp=6c18df2143ee7872868909b9c37279b2292c2189;hpb=5512a41c689e231cee170fce3cfd015384921b47;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/registry.rb b/lib/rbot/registry.rb index 6c18df21..61d4b33e 100644 --- a/lib/rbot/registry.rb +++ b/lib/rbot/registry.rb @@ -57,6 +57,15 @@ class Registry @libpath = File.join(File.dirname(__FILE__), 'registry') @format = format load File.join(@libpath, @format+'.rb') if format + # The get_impl method will return all implementations of the + # abstract accessor interface, since we only ever load one + # (the configured one) accessor implementation, we can just assume + # it to be the correct accessor to use. + accessors = AbstractAccessor.get_impl + if accessors.length > 1 + warning 'multiple accessor implementations loaded!' + end + @accessor_class = accessors.first end # Returns a list of supported registry database formats. @@ -68,12 +77,9 @@ class Registry # Creates a new Accessor object for the specified database filename. def create(path, filename) - # The get_impl method will return a list of all the classes that - # implement the accessor interface, since we only ever load one - # (the configured one) accessor implementation, we can just assume - # it to be the correct accessor to use. - cls = AbstractAccessor.get_impl.first - cls.new(File.join(path, 'registry_' + @format, filename.downcase)) + db = @accessor_class.new(File.join(path, 'registry_' + @format, filename.downcase)) + db.optimize + db end # Helper method that will return a list of supported registry formats. @@ -81,26 +87,41 @@ class Registry @@formats ||= Registry.new.discover end + # Will detect tokyocabinet registry location: ~/.rbot/registry/*.tdb + # and move it to its new location ~/.rbot/registry_tc/*.tdb + def migrate_registry_folder(path) + old_name = File.join(path, 'registry') + new_name = File.join(path, 'registry_tc') + if @format == 'tc' and File.exists?(old_name) and + not File.exists?(new_name) and + not Dir.glob(File.join(old_name, '*.tdb')).empty? + File.rename(old_name, new_name) + end + end + # Abstract database accessor (a hash-like interface). class AbstractAccessor + attr_reader :filename + # lets the user define a recovery procedure in case the Marshal # deserialization fails, it might be manually recover data. # NOTE: weird legacy stuff, used by markov plugin (WTH?) attr_accessor :recovery def initialize(filename) - debug 'init registry accessor for: ' + filename + debug "init registry accessor of #{self.class} for: #{filename}" @filename = filename @name = File.basename filename @registry = nil @default = nil @recovery = nil + @sub_registries = {} end def sub_registry(prefix) path = File.join(@filename.gsub(/\.[^\/\.]+$/,''), prefix.to_s) - return self.class.new(path) + @sub_registries[path] ||= self.class.new(path) end # creates the registry / subregistry folders @@ -173,13 +194,13 @@ class Registry # Forces flush/sync the database on disk. def flush return unless @registry - @registry.flush + # if not supported by the database, close/reopen: + close + registry end - # Should optimize/vacuum the database. + # Should optimize/vacuum the database. (if supported) def optimize - return unless @registry - @registry.optimize end # Closes the database. @@ -206,8 +227,8 @@ class Registry # like Hash#each def each(&block) return nil unless dbexists? - registry.each do |key| - block.call(key, self[key]) + registry.each do |key, value| + block.call(key, restore(value)) end end @@ -252,9 +273,13 @@ class Registry end # delete a key from the registry + # returns the value in success, nil otherwise def delete(key) return default unless dbexists? - return registry.delete(key.to_s) + value = registry.delete(key.to_s) + if value + restore(value) + end end # returns a list of your keys @@ -263,12 +288,6 @@ class Registry return registry.keys end - # just like Hash#has_both? - def has_both?(key, value) - return false unless dbexists? - registry.has_key?(key.to_s) and registry.has_value?(store(value)) - end - # Return an array of all associations [key, value] in your namespace def to_a return [] unless dbexists? @@ -315,7 +334,7 @@ class Registry # Returns all classes from the namespace that implement this interface def self.get_impl - ObjectSpace.each_object(Class).select { |klass| klass < self } + ObjectSpace.each_object(Class).select { |klass| klass.ancestors[1] == self } end end