Module: DwCR::Metaschema

Defined in:
lib/dwcr/metaschema/metaschema.rb,
lib/dwcr/metaschema/entity.rb,
lib/dwcr/metaschema/archive.rb,
lib/dwcr/metaschema/attribute.rb,
lib/dwcr/metaschema/content_file.rb,
lib/dwcr/metaschema/xml_parsable.rb

Overview

This module provides functionality to create, update, and verify the part of the DwCR schema needed to persist information about the DwCR

Defined Under Namespace

Modules: XMLParsable Classes: Archive, Attribute, ContentFile, Entity

Class Method Summary collapse

Class Method Details

.columns?(table, *columns) ⇒ Boolean

Performs an integrety check on table, veryfies all columns are present with the parameters given in columns; a column parameter is an array with the structure: [:column_name, :column_type, {column_options} ]

Returns:

  • (Boolean)


46
47
48
49
50
51
# File 'lib/dwcr/metaschema/metaschema.rb', line 46

def self.columns?(table, *columns)
  db_cols = inspect_table(table, :schema)
  return unless db_cols
  exp_cols = columns.map(&:first).unshift(:id)
  exp_cols == db_cols.map(&:first)
end

.createObject

Creates the tables for the metaschema present in every DwCR archives, entities, attributes, content_files loads the Sequel::Model classes for these tables



13
14
15
16
17
18
19
20
21
22
# File 'lib/dwcr/metaschema/metaschema.rb', line 13

def self.create
  tabledefs = Psych.load_file(File.join(__dir__, 'metaschema_tables.yml'))
  tabledefs.to_h.each do |table, columns|
    DB.create_table? table do
      primary_key :id
      columns.each { |c| column(*c) }
    end
  end
  load_models
end

.indexes?(table, *columns) ⇒ Boolean

Performs an integrety check on table, veryfies all indices are present with the parameters given in columns; a column parameter is an array with the structure: [:column_name, :column_type, {column_options} ]

Returns:

  • (Boolean)


57
58
59
60
61
62
63
# File 'lib/dwcr/metaschema/metaschema.rb', line 57

def self.indexes?(table, *columns)
  db_idxs = inspect_table(table, :indexes)
  return unless db_idxs
  exp_idxs = columns.select { |column| column[2]&.fetch(:index, false) }
                    .map(&:first)
  exp_idxs & db_idxs.values.map { |x| x[:columns] }.flatten == exp_idxs
end

.inspect_table(table, method) ⇒ Object

Returns schema or index parameters for a table, depending on the second argument (:schema or :indexes) returns false if the table does not exist



35
36
37
38
39
40
# File 'lib/dwcr/metaschema/metaschema.rb', line 35

def self.inspect_table(table, method)
  DB.indexes(table).values.map { |x| x[:columns] }.flatten
  DB.send(method, table)
rescue Sequel::Error
  false
end

.load_modelsObject

Loads all Sequel::Model classes for the metaschema



25
26
27
28
29
30
# File 'lib/dwcr/metaschema/metaschema.rb', line 25

def self.load_models
  require_relative 'archive'
  require_relative 'entity'
  require_relative 'attribute'
  require_relative 'content_file'
end

.update(archive, **options) ⇒ Object

Updates all Attribute instances in a Archive with parameters from files in ContentFile schema_options: a Hash with attribute names as keys and boolean values { :type => true, :length => true } updates any attribute given as key where value is true



70
71
72
73
74
75
76
77
# File 'lib/dwcr/metaschema/metaschema.rb', line 70

def self.update(archive, **options)
  return if options.empty?

  # FIXME: handle situation where schema tables have been created
  options.select! { |_k, v| v == true }
  archive.entities
         .each { |entity| entity.update_attributes!(*options.keys) }
end

.valid?Boolean

Performs an integrity check on the metaschema in the DWCR file (the current database connection) returns true if all tables, columns, and indices as given in config/metaschema_tables.yml are present

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
91
92
# File 'lib/dwcr/metaschema/metaschema.rb', line 83

def self.valid?
  tabledefs = Psych.load_file('lib/dwcr/metaschema/metaschema_tables.yml')
  status = tabledefs.map do |td|
    table = td.first
    columns = td.last
    columns?(table, *columns) && indexes?(table, *columns)
  end
  return false if status.uniq.size > 1
  status.first
end