Class: Mailmate::IndexReader
- Inherits:
-
Object
- Object
- Mailmate::IndexReader
- Defined in:
- lib/mailmate/index_reader.rb
Constant Summary collapse
- RECORD_SIZE =
12
Instance Attribute Summary collapse
- #name ⇒ Object readonly
Class Method Summary collapse
-
.for(name) ⇒ Object
Per-process cache of readers keyed by [name, db_headers].
-
.reset!(name = nil) ⇒ Object
Invalidate cached readers.
Instance Method Summary collapse
-
#each_eml_id(&block) ⇒ Object
Iterate every recorded eml-id.
-
#each_record ⇒ Object
Iterate every (eml_id, raw_value) pair.
-
#flags_for(eml_id) ⇒ Object
‘#flags.flag` semantics: the cache stores a space-separated list of IMAP keywords.
-
#initialize(name) ⇒ IndexReader
constructor
A new instance of IndexReader.
-
#size ⇒ Object
Number of records (mostly for diagnostics).
-
#value_for(eml_id) ⇒ Object
Returns the raw cached value for a given .eml body-part ID, or nil if the message isn’t in this index.
Constructor Details
#initialize(name) ⇒ IndexReader
Returns a new instance of IndexReader.
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/mailmate/index_reader.rb', line 63 def initialize(name) @name = name base = "#{Mailmate.config.db_headers}/#{name}" raise ArgumentError, "Index not found: #{name} (looked at #{base}.{cache,offsets})" \ unless File.exist?("#{base}.cache") && File.exist?("#{base}.offsets") @cache_bytes = File.binread("#{base}.cache") @offsets_bytes = File.binread("#{base}.offsets") build_index! end |
Instance Attribute Details
#name ⇒ Object (readonly)
61 62 63 |
# File 'lib/mailmate/index_reader.rb', line 61 def name @name end |
Class Method Details
.for(name) ⇒ Object
Per-process cache of readers keyed by [name, db_headers]. Including db_headers means a Mailmate.config swap (e.g. a test pointing at a different tmpdir) doesn’t return stale readers built from the old path.
36 37 38 39 |
# File 'lib/mailmate/index_reader.rb', line 36 def for(name) @cache ||= {} @cache[cache_key(name)] ||= new(name) end |
.reset!(name = nil) ⇒ Object
Invalidate cached readers. With no argument, drops the entire cache (useful for tests or when MailMate’s database swaps out). With a name, invalidates only entries for that name across all db_headers — the common case (cache-bust after a write) doesn’t need to thread config through.
46 47 48 49 50 51 52 |
# File 'lib/mailmate/index_reader.rb', line 46 def reset!(name = nil) if name.nil? @cache = nil elsif @cache @cache.delete_if { |(n, _dir), _reader| n == name } end end |
Instance Method Details
#each_eml_id(&block) ⇒ Object
Iterate every recorded eml-id. Yields just the id; callers that also want the value should pair this with ‘value_for`. Exists so other gem modules don’t have to reach into ‘@index` directly.
98 99 100 101 |
# File 'lib/mailmate/index_reader.rb', line 98 def each_eml_id(&block) return enum_for(:each_eml_id) unless block @index.each_key(&block) end |
#each_record ⇒ Object
Iterate every (eml_id, raw_value) pair. The value comes back as the bare cache substring; callers that need parsed form (e.g. flag tokens) should massage it themselves.
106 107 108 109 110 111 |
# File 'lib/mailmate/index_reader.rb', line 106 def each_record return enum_for(:each_record) unless block_given? @index.each_key do |eml_id| yield eml_id, value_for(eml_id) end end |
#flags_for(eml_id) ⇒ Object
‘#flags.flag` semantics: the cache stores a space-separated list of IMAP keywords. Split into individual flag tokens.
84 85 86 87 88 |
# File 'lib/mailmate/index_reader.rb', line 84 def flags_for(eml_id) v = value_for(eml_id) return [] if v.nil? || v.empty? v.split(/\s+/).reject(&:empty?) end |
#size ⇒ Object
Number of records (mostly for diagnostics).
91 92 93 |
# File 'lib/mailmate/index_reader.rb', line 91 def size @index.size end |
#value_for(eml_id) ⇒ Object
Returns the raw cached value for a given .eml body-part ID, or nil if the message isn’t in this index.
76 77 78 79 80 |
# File 'lib/mailmate/index_reader.rb', line 76 def value_for(eml_id) pair = @index[eml_id.to_i] return nil unless pair @cache_bytes[pair[0]...pair[1]] end |