Class: MarkdownServer::CsvBrowser::ConfigLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/markdown_server/csv_browser/config_loader.rb

Overview

Loads database definitions from YAML files. Each YAML file defines one database with its tables, schemas, and views. CSV paths are resolved relative to the YAML file’s directory.

Defined Under Namespace

Classes: Column, Database, Table, View

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(yaml_paths, root_dir) ⇒ ConfigLoader

Returns a new instance of ConfigLoader.



18
19
20
21
22
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 18

def initialize(yaml_paths, root_dir)
  @yaml_paths = yaml_paths
  @root_dir = root_dir
  @databases = yaml_paths.filter_map { |path| load_database(path) }
end

Instance Attribute Details

#databasesObject (readonly)

Returns the value of attribute databases.



24
25
26
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 24

def databases
  @databases
end

Instance Method Details

#database(key) ⇒ Object



36
37
38
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 36

def database(key)
  @databases.find { |db| db.key == key }
end

#find_database_by_yaml_path(real_path) ⇒ Object

Returns Database if real_path matches a configured YAML database file



41
42
43
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 41

def find_database_by_yaml_path(real_path)
  @databases.find { |db| db.yaml_path == real_path }
end

#find_table_by_csv_path(real_path) ⇒ Object

Returns [database, table] if real_path matches a table’s CSV file, or nil



88
89
90
91
92
93
94
95
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 88

def find_table_by_csv_path(real_path)
  @databases.each do |db|
    db.tables.each do |table|
      return [db, table] if table.csv_path == real_path
    end
  end
  nil
end

#reload!Object



26
27
28
29
30
31
32
33
34
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 26

def reload!
  config_path = File.join(@root_dir, ".markdownr.yml")
  if File.exist?(config_path)
    yaml = YAML.safe_load(File.read(config_path), permitted_classes: [Symbol], aliases: true) rescue nil
    paths = yaml&.dig("csv_databases") || yaml&.dig("plugins", "csv_browser", "databases")
    @yaml_paths = paths if paths.is_a?(Array) && !paths.empty?
  end
  @databases = @yaml_paths.filter_map { |path| load_database(path) }
end

#resolve_references(database, table) ⇒ Object

Builds FK lookup maps for a table’s columns that have references. Returns { “column_key” => { id_value => display_value, … }, … }



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 47

def resolve_references(database, table)
  lookups = {}
  table.columns.each do |col|
    next unless col.references
    ref_table = database.tables.find { |t| t.key == col.references[:table] }
    next unless ref_table
    next unless File.exist?(ref_table.csv_path)

    map = {}
    CSV.foreach(ref_table.csv_path, headers: true) do |row|
      key_val = row[col.references[:column]]
      display_val = row[col.references[:display]]
      map[key_val] = display_val if key_val && display_val
    end
    lookups[col.key] = map
  end
  lookups
end

#resolve_reverse_references(database, table) ⇒ Object

Finds other tables in the database that have FK columns pointing at this table. Returns [{ table: “enrollments”, label: “Enrollments”, column: “class_id”, references_column: “id” }, …]



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 68

def resolve_reverse_references(database, table)
  reverse = []
  database.tables.each do |other_table|
    next if other_table.key == table.key
    other_table.columns.each do |col|
      next unless col.references && col.references[:table] == table.key
      entry = {
        table: other_table.key,
        title: other_table.title,
        column: col.key,
        references_column: col.references[:column]
      }
      entry[:color] = other_table.color if other_table.color
      reverse << entry
    end
  end
  reverse
end

#unmapped_csv_filesObject

Returns CSV file paths under root_dir that aren’t claimed by any database table. Each entry is { path: “/abs/path.csv”, relative: “sub/dir/file.csv” }.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/markdown_server/csv_browser/config_loader.rb', line 99

def unmapped_csv_files
  referenced = Set.new
  @databases.each do |db|
    db.tables.each { |t| referenced << t.csv_path }
  end

  root = File.realpath(@root_dir)
  Dir.glob(File.join(root, "**", "*.csv")).filter_map do |path|
    real = File.realpath(path)
    next if referenced.include?(real)
    relative = real.delete_prefix("#{root}/")
    { path: real, relative: relative }
  end.sort_by { |e| e[:relative] }
end