class RIMS::MailStore
Constants
- MSG_FLAG_NAMES
Public Class Methods
build(unique_user_id, kvs_meta_open, kvs_text_open)
click to toggle source
# File lib/rims/mail_store.rb, line 34 def self.build(unique_user_id, kvs_meta_open, kvs_text_open) kvs_build = proc{|kvs_open, db_name| kvs_open.call(MAILBOX_DATA_STRUCTURE_VERSION, unique_user_id, db_name) } mail_store = MailStore.new(DB::Meta.new(kvs_build.call(kvs_meta_open, 'meta')), DB::Message.new(kvs_build.call(kvs_text_open, 'message'))) {|mbox_id| DB::Mailbox.new(kvs_build.call(kvs_meta_open, "mailbox_#{mbox_id}")) } mail_store.add_mbox('INBOX') unless mail_store.mbox_id('INBOX') mail_store end
new(meta_db, msg_db) { |mbox_id| ... }
click to toggle source
# File lib/rims/mail_store.rb, line 12 def initialize(meta_db, msg_db, &mbox_db_factory) # :yields: mbox_id @rw_lock = ReadWriteLock.new @meta_db = meta_db @msg_db = msg_db @mbox_db_factory = mbox_db_factory @mbox_db = {} @meta_db.each_mbox_id do |mbox_id| @mbox_db[mbox_id] = nil end if (@meta_db.dirty?) then @abort_transaction = true else @abort_transaction = false @meta_db.dirty = true end @channel = ServerResponseChannel.new end
Public Instance Methods
abort_transaction?()
click to toggle source
# File lib/rims/mail_store.rb, line 57 def abort_transaction? @abort_transaction end
add_mbox(name)
click to toggle source
# File lib/rims/mail_store.rb, line 152 def add_mbox(name) transaction{ name = 'INBOX' if (name =~ /\A INBOX \z/xi) name = name.b mbox_id = @meta_db.add_mbox(name) @mbox_db[mbox_id] = nil @meta_db.cnum_succ! mbox_id } end
add_msg(mbox_id, msg_text, msg_date=Time.now)
click to toggle source
# File lib/rims/mail_store.rb, line 235 def add_msg(mbox_id, msg_text, msg_date=Time.now) transaction{ mbox_db = get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." msg_id = @meta_db.msg_id_succ! @msg_db.add_msg(msg_id, msg_text) @meta_db.set_msg_date(msg_id, msg_date) @meta_db.set_msg_flag(msg_id, 'recent', true) uid = @meta_db.add_msg_mbox_uid(msg_id, mbox_id) mbox_db.add_msg(uid, msg_id) @meta_db.cnum_succ! uid } end
close()
click to toggle source
# File lib/rims/mail_store.rb, line 119 def close @mbox_db.each_value do |db| db.close if db end @msg_db.close @meta_db.dirty = false unless @abort_transaction @meta_db.close self end
cnum()
click to toggle source
# File lib/rims/mail_store.rb, line 140 def cnum @meta_db.cnum end
copy_msg(src_uid, src_mbox_id, dst_mbox_id)
click to toggle source
# File lib/rims/mail_store.rb, line 266 def copy_msg(src_uid, src_mbox_id, dst_mbox_id) transaction{ src_mbox_db = get_mbox_db(src_mbox_id) or raise "not found a source mailbox: #{src_mbox_id}" dst_mbox_db = get_mbox_db(dst_mbox_id) or raise "not found a destination mailbox: #{dst_mbox_id}" msg_id = src_mbox_db.msg_id(src_uid) or raise "not found a message: #{src_mbox_id},#{src_uid}" dst_uid = @meta_db.add_msg_mbox_uid(msg_id, dst_mbox_id) dst_mbox_db.add_msg(dst_uid, msg_id) @meta_db.cnum_succ! dst_uid } end
del_mbox(mbox_id)
click to toggle source
# File lib/rims/mail_store.rb, line 166 def del_mbox(mbox_id) transaction{ mbox_name = @meta_db.mbox_name(mbox_id) or raise "not found a mailbox: #{mbox_id}." get_mbox_db(mbox_id) mbox_db = @mbox_db.delete(mbox_id) mbox_db.each_msg_uid do |uid| msg_id = mbox_db.msg_id(uid) del_msg(msg_id, mbox_id, uid) end mbox_db.close mbox_db.destroy for name in MSG_FLAG_NAMES @meta_db.clear_mbox_flag_num(mbox_id, name) end @meta_db.del_mbox(mbox_id) or raise 'internal error.' @meta_db.cnum_succ! mbox_name } end
each_mbox_id() { |mbox_id| ... }
click to toggle source
# File lib/rims/mail_store.rb, line 215 def each_mbox_id return enum_for(:each_mbox_id) unless block_given? @meta_db.each_mbox_id do |mbox_id| yield(mbox_id) end self end
each_msg_uid(mbox_id) { |uid| ... }
click to toggle source
# File lib/rims/mail_store.rb, line 336 def each_msg_uid(mbox_id) mbox_db = get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." return enum_for(:each_msg_uid, mbox_id) unless block_given? mbox_db.each_msg_uid do |uid| yield(uid) end self end
expunge_mbox(mbox_id) { |uid| ... }
click to toggle source
# File lib/rims/mail_store.rb, line 345 def expunge_mbox(mbox_id) transaction{ mbox_db = get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." uid_list = mbox_db.each_msg_uid.find_all{|uid| mbox_db.msg_flag_deleted(uid) } msg_id_list = uid_list.map{|uid| mbox_db.msg_id(uid) } uid_list.zip(msg_id_list) do |uid, msg_id| mbox_db.expunge_msg(uid) del_msg(msg_id, mbox_id, uid) yield(uid) if block_given? end @meta_db.cnum_succ! self } end
mbox_flag_num(mbox_id, flag_name)
click to toggle source
# File lib/rims/mail_store.rb, line 227 def mbox_flag_num(mbox_id, flag_name) if (MSG_FLAG_NAMES.include? flag_name) then @meta_db.mbox_flag_num(mbox_id, flag_name) else raise "unknown flag name: #{name}" end end
mbox_id(mbox_name)
click to toggle source
# File lib/rims/mail_store.rb, line 210 def mbox_id(mbox_name) mbox_name = 'INBOX' if (mbox_name =~ /\A INBOX \z/xi) @meta_db.mbox_id(mbox_name.b) end
mbox_msg_num(mbox_id)
click to toggle source
# File lib/rims/mail_store.rb, line 223 def mbox_msg_num(mbox_id) @meta_db.mbox_msg_num(mbox_id) end
mbox_name(mbox_id)
click to toggle source
# File lib/rims/mail_store.rb, line 204 def mbox_name(mbox_id) if (name = @meta_db.mbox_name(mbox_id)) then name.dup.force_encoding('utf-8') end end
msg_date(mbox_id, uid)
click to toggle source
# File lib/rims/mail_store.rb, line 292 def msg_date(mbox_id, uid) mbox_db = get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." msg_id = mbox_db.msg_id(uid) or raise "not found a message: #{mbox_id},#{uid}" @meta_db.msg_date(msg_id) end
msg_exist?(mbox_id, uid)
click to toggle source
# File lib/rims/mail_store.rb, line 281 def msg_exist?(mbox_id, uid) mbox_db = get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." mbox_db.msg_exist? uid end
msg_flag(mbox_id, uid, flag_name)
click to toggle source
# File lib/rims/mail_store.rb, line 298 def msg_flag(mbox_id, uid, flag_name) mbox_db = get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." if ((MSG_FLAG_NAMES - %w[ deleted ]).include? flag_name) then msg_id = mbox_db.msg_id(uid) or raise "not found a message: #{mbox_id},#{uid}" @meta_db.msg_flag(msg_id, flag_name) elsif (flag_name == 'deleted') then mbox_db.msg_flag_deleted(uid) else raise "unknown flag name: #{flag_name}" end end
msg_text(mbox_id, uid)
click to toggle source
# File lib/rims/mail_store.rb, line 286 def msg_text(mbox_id, uid) mbox_db = get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." msg_id = mbox_db.msg_id(uid) or raise "not found a message: #{mbox_id},#{uid}" @msg_db.msg_text(msg_id) end
open_folder(mbox_id, read_only: false)
click to toggle source
# File lib/rims/mail_store.rb, line 364 def open_folder(mbox_id, read_only: false) @meta_db.mbox_name(mbox_id) or raise "not found a mailbox: #{mbox_id}." MailFolder.new(mbox_id, self, read_only: read_only).attach(@channel) end
recovery_data(logger: Logger.new(STDOUT))
click to toggle source
# File lib/rims/mail_store.rb, line 77 def recovery_data(logger: Logger.new(STDOUT)) begin logger.info('test read all: meta DB') @meta_db.test_read_all do |error| logger.error("read fail: #{error}") end logger.info('test read all: msg DB') @msg_db.test_read_all do |error| logger.error("read fail: #{error}") end @mbox_db.each_key do |mbox_id| logger.info("test_read_all: mailbox DB #{mbox_id}") get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." @mbox_db[mbox_id].test_read_all do |error| logger.error("read fail: #{error}") end end @meta_db.recovery_start @meta_db.recovery_phase1_msg_scan(@msg_db, logger: logger) @meta_db.recovery_phase2_msg_scan(@msg_db, logger: logger) @meta_db.recovery_phase3_mbox_scan(logger: logger) @meta_db.recovery_phase4_mbox_scan(logger: logger) @meta_db.recovery_phase5_mbox_repair(logger: logger) {|mbox_id| if (@mbox_db.key? mbox_id) then raise "not a lost mailbox: #{mbox_id}" else @mbox_db[mbox_id] = nil get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." end } @meta_db.recovery_phase6_msg_scan(@mbox_db, logger: logger) @meta_db.recovery_phase7_mbox_msg_scan(@mbox_db, MSG_FLAG_NAMES, logger: logger) @meta_db.recovery_phase8_lost_found(@mbox_db, logger: logger) @meta_db.recovery_end ensure @abort_transaction = ! $!.nil? end self end
rename_mbox(mbox_id, new_name)
click to toggle source
# File lib/rims/mail_store.rb, line 190 def rename_mbox(mbox_id, new_name) transaction{ old_name = @meta_db.mbox_name(mbox_id) or raise "not found a mailbox: #{mbox_id}." old_name = old_name.dup.force_encoding('utf-8') new_name = 'INBOX' if (new_name =~ /\A INBOX \z/xi) @meta_db.rename_mbox(mbox_id, new_name.b) @meta_db.cnum_succ! old_name } end
set_msg_flag(mbox_id, uid, flag_name, flag_value)
click to toggle source
# File lib/rims/mail_store.rb, line 311 def set_msg_flag(mbox_id, uid, flag_name, flag_value) transaction{ mbox_db = get_mbox_db(mbox_id) or raise "not found a mailbox: #{mbox_id}." if ((MSG_FLAG_NAMES - %w[ deleted ]).include? flag_name) then msg_id = mbox_db.msg_id(uid) or raise "not found a message: #{mbox_id},#{uid}" @meta_db.set_msg_flag(msg_id, flag_name, flag_value) elsif (flag_name == 'deleted') then prev_deleted = mbox_db.msg_flag_deleted(uid) mbox_db.set_msg_flag_deleted(uid, flag_value) if (! prev_deleted && flag_value) then @meta_db.mbox_flag_num_increment(mbox_id, 'deleted') elsif (prev_deleted && ! flag_value) then @meta_db.mbox_flag_num_decrement(mbox_id, 'deleted') end else raise "unknown flag name: #{flag_name}" end @meta_db.cnum_succ! self } end
sync()
click to toggle source
# File lib/rims/mail_store.rb, line 129 def sync transaction{ @msg_db.sync @mbox_db.each_value do |db| db.sync if db end @meta_db.sync self } end
transaction() { || ... }
click to toggle source
# File lib/rims/mail_store.rb, line 61 def transaction if (@abort_transaction) then raise 'abort transaction.' end transaction_completed = false begin return_value = yield transaction_completed = true ensure @abort_transaction = true unless transaction_completed end return_value end
uid(mbox_id)
click to toggle source
# File lib/rims/mail_store.rb, line 144 def uid(mbox_id) @meta_db.mbox_uid(mbox_id) end
uidvalidity()
click to toggle source
# File lib/rims/mail_store.rb, line 148 def uidvalidity @meta_db.uidvalidity end
Private Instance Methods
del_msg(msg_id, mbox_id, uid)
click to toggle source
# File lib/rims/mail_store.rb, line 253 def del_msg(msg_id, mbox_id, uid) mbox_uid_map = @meta_db.del_msg_mbox_uid(msg_id, mbox_id, uid) if (mbox_uid_map.empty?) then @meta_db.clear_msg_date(msg_id) @meta_db.clear_msg_flag(msg_id) @meta_db.clear_msg_mbox_uid_mapping(msg_id) @msg_db.del_msg(msg_id) end @meta_db.mbox_flag_num_decrement(mbox_id, 'deleted') nil end
get_mbox_db(mbox_id)
click to toggle source
# File lib/rims/mail_store.rb, line 50 def get_mbox_db(mbox_id) if (@mbox_db.key? mbox_id) then @mbox_db[mbox_id] ||= @mbox_db_factory.call(mbox_id) end end