5 # :title: Registry import/export and migration.
7 # You can use this script to,
8 # - backup the rbot registry in a format that is platform independent
10 # - migrate old rbot registries bdb (ruby 1.8) and tokyocabinet.
12 # Author:: apoc (Matthias Hecker) <apoc@geekosphere.org>
13 # Copyright:: (C) 2014 Matthias Hecker
16 begin; require 'rubygems'; rescue Exception; puts "[#{$!}]"; end
17 begin; require 'dbm'; rescue Exception; puts "[#{$!}]"; end
18 begin; require 'bdb'; rescue Exception; puts "[#{$!}]"; end
19 begin; require 'tokyocabinet'; rescue Exception; puts "[#{$!}]"; end
21 puts 'RBot registry backup/import script.'
22 puts 'Ruby: %s | DBM: %s | BDB: %s | TC: %s' % [RUBY_VERSION,
23 (DBM::VERSION rescue '-'),
24 (BDB::VERSION rescue '-'),
25 (TokyoCabinet::VERSION rescue '-')]
27 if ARGV.length > 3 or ARGV.length < 2
29 Usage rbotdb [backup|restore] <BACKUP/RESTORE-FILE> [<PROFILE>]
32 rbotdb backup ~/rbot_db_backup.yaml
33 rbotdb backup ~/rbot_db_backup.yaml.gz ~/.rbot_two
34 rbotdb restore ~/rbot_db_backup.yaml
39 mode = ARGV[0] if %w{backup restore}.include? ARGV[0]
40 file = File.expand_path ARGV[1]
41 profile = File.expand_path(ARGV[2] ? ARGV[2] : '~/.rbot')
46 def initialize(registry, path)
54 File.expand_path(File.join(@registry, @path))
60 File.file?(abs) and %w{.db .tdb}.include? ext
64 def initialize(profile)
66 @registry = File.join(profile, './registry')
69 # list all database files:
71 return nil if not File.directory? @registry
73 Dir.glob(File.join('**', '*')).map do |name|
74 RegistryFile.new(@registry, name)
81 next unless file.ext == ext
83 db = loadBDB(file) if not db
84 db = loadTC(file) if not db
86 puts 'ERROR: unable to load db: %s, last error: %s' % [file.abs, $last_error]
88 puts 'Loaded: %s [%d values]' % [file.abs, db.length]
95 File.open(file, 'w') do |f|
96 f.write(Marshal.dump(@data))
105 dbm = DBM.open(path.gsub(/\.[^\.]+$/,''), 0666, DBM::READER)
109 $last_error = "[%s]\n%s" % [$!, $@.join("\n")]
117 db = BDB::Hash.open(path, nil, 'r')
119 db.each do |key, value|
124 $last_error = "[%s]\n%s" % [$!, $@.join("\n")]
132 db = TokyoCabinet::BDB.new
133 db.open(path, TokyoCabinet::BDB::OREADER)
135 db.each do |key, value|
140 $last_error = "[%s]\n%s" % [$!, $@.join("\n")]
146 puts 'mode = ' + mode
147 puts 'profile= ' + profile
148 puts 'file = ' + file
152 backup = Backup.new(profile)
155 puts 'ERROR! Backup file already exists!'
164 registry = File.join(profile, './registry')
166 data = Marshal.load File.read(file)
167 data.each_pair do |path, db|
168 path = File.expand_path(File.join(registry, path))
170 # create directories:
171 dirs = File.dirname(path).split("/")
172 dirs.length.times { |i|
173 dir = dirs[0,i+1].join("/")+"/"
174 unless File.exist?(dir)
175 puts 'create subdir:'+dir
179 path.gsub!(/\.([^\.]+)$/,'')
181 if File.exists? path+'.db' or File.exists? path+'.tdb'
182 raise 'error, unable to restore to existing db'
185 puts 'restore to: '+path
186 dbm = DBM.open(path, 0666, DBM::WRCREAT)
187 db.each_pair do |key, value|