Class: MPS::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/mps/store.rb

Instance Method Summary collapse

Constructor Details

#initialize(storage_dir) ⇒ Store

Returns a new instance of Store.



5
6
7
8
9
10
# File 'lib/mps/store.rb', line 5

def initialize(storage_dir)
  @storage_dir     = storage_dir
  @element_classes = Elements.constants
    .map    { |k| Elements.const_get(k) }
    .select { |x| x.class == Class }
end

Instance Method Details

#all_filesObject

All .mps files in storage, sorted by filename (chronological).



47
48
49
50
51
# File 'lib/mps/store.rb', line 47

def all_files
  Dir[File.join(@storage_dir, "*.#{Constants::MPS_EXT}")]
    .select { |f| File.basename(f) =~ Constants::MPS_FILE_NAME_REGEXP }
    .sort
end

#append(type:, body:, tags: [], attrs: {}, date: Date.today) ⇒ Object

Appends a new element to today’s (or date‘s) file. Returns the file path.



38
39
40
41
42
43
44
# File 'lib/mps/store.rb', line 38

def append(type:, body:, tags: [], attrs: {}, date: Date.today)
  args_parts = attrs.map { |k, v| "#{k}: #{v}" } + Array(tags)
  args_str   = args_parts.join(", ")
  path       = find_or_create_path(date)
  File.open(path, "a") { |f| f.write("\n@#{type}[#{args_str}]{\n  #{body}\n}\n") }
  path
end

#files_since(since_date) ⇒ Object

Files whose date-stamp is >= since_date.



54
55
56
57
# File 'lib/mps/store.rb', line 54

def files_since(since_date)
  since_str = since_date.strftime("%Y%m%d")
  all_files.select { |f| File.basename(f).slice(0, 8) >= since_str }
end

#find_file(date) ⇒ Object

First .mps file found for date, or nil.



13
14
15
# File 'lib/mps/store.rb', line 13

def find_file(date)
  find_files(date).first
end

#find_files(date) ⇒ Object

All .mps files matching date (handles multiple files per day).



18
19
20
21
22
23
# File 'lib/mps/store.rb', line 18

def find_files(date)
  date_str = date.strftime("%Y%m%d")
  Dir[File.join(@storage_dir, "#{date_str}*.#{Constants::MPS_EXT}")]
    .select { |f| File.basename(f) =~ Constants::MPS_FILE_NAME_REGEXP }
    .sort
end

#find_or_create_path(date) ⇒ Object

Existing file for date, or a generated new path (file not yet created).



26
27
28
# File 'lib/mps/store.rb', line 26

def find_or_create_path(date)
  find_file(date) || File.join(@storage_dir, Constants::MPS_NEW_FILE_NAME_GEN.call(date))
end

#parse_date(date) ⇒ Object

Parsed elements hash for date. Returns {} when no file exists.



31
32
33
34
35
# File 'lib/mps/store.rb', line 31

def parse_date(date)
  path = find_file(date)
  return {} unless path
  Engines::Parser.parse_mps_file_to_elements_hash(path, @element_classes)
end

#search(query, type_filter: nil, tag_filter: nil, since_date: nil) ⇒ Object

Full-text search across files. Returns [file:, date_str:]. since_date is a Date; type_filter and tag_filter are strings.



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/mps/store.rb', line 61

def search(query, type_filter: nil, tag_filter: nil, since_date: nil)
  files = since_date ? files_since(since_date) : all_files
  files.flat_map do |file|
    date_str = File.basename(file).slice(0, 8)
    Engines::Parser.parse_mps_file_to_elements_hash(file, @element_classes)
      .values
      .reject { |e| e.is_a?(Elements::MPS) }
      .select { |e| type_filter.nil? || e.class::SIGNATURE_STAMP == type_filter }
      .select { |e| tag_filter.nil?  || e.tags.include?(tag_filter) }
      .select { |e| query.nil?       || e.body_str.downcase.include?(query.downcase) }
      .map    { |e| { element: e, file: file, date_str: date_str } }
  end
end