Class: Ditto::Entity
- Inherits:
-
Object
- Object
- Ditto::Entity
- Defined in:
- lib/ditto/entity.rb
Constant Summary collapse
- PROPS =
[ :mandatory, :unique, :related ].freeze
- @@entities =
Entities are stored in a hash keyed by entity name The contents are an array of Entity objects one for each version
Hash.new {|h,k| h[k] = []}
- @@instances =
Instances are stored in a hash keyed by entity name The contents are a hash (keyed by version) of arrays of instance hashes
Hash.new {|h,k| h[k] = Hash.new{|i,j|i[j] = []}}
Instance Attribute Summary collapse
-
#deps ⇒ Object
readonly
Returns the value of attribute deps.
-
#fields ⇒ Object
readonly
Returns the value of attribute fields.
-
#loc ⇒ Object
readonly
Returns the value of attribute loc.
-
#methods ⇒ Object
readonly
Returns the value of attribute methods.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Class Method Summary collapse
-
.dep_list(name, list, done) ⇒ Object
Compute dependencies recursively build a list in dependency sequence.
-
.find_entity(name, version) ⇒ Object
Given the input data version get the right entity.
- .find_map(entity, type) ⇒ Object
-
.load_entities(filepath, verbose = 0) ⇒ Object
Load entities required by the instances.
-
.load_from_file(f) ⇒ Object
Errors discovered in here will be load/syntax errors Stack depth is just empirically determined! TODO WRITE A TEST!.
-
.load_instances(f, verbose = 0) ⇒ Object
Load data from YAML files into the in-memory representation return number of instances loaded if all OK.
- .reset ⇒ Object
-
.store_all(verbose = 0) ⇒ Object
Store the instances in dependency order.
Instance Method Summary collapse
-
#initialize(name, version, fields, methods) ⇒ Entity
constructor
Maps to the ‘entity’ DSL keyword Stack depth is just empirically determined! TODO WRITE A TEST!.
Constructor Details
#initialize(name, version, fields, methods) ⇒ Entity
Maps to the ‘entity’ DSL keyword Stack depth is just empirically determined! TODO WRITE A TEST!
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/ditto/entity.rb', line 26 def initialize name, version, fields, methods src = Thread.current.backtrace[3].split(':')[0..1] @name = name.to_sym @version = Gem::Version.new(version) rescue raise(Error.new(src), "#{name}: #{$!.}") @methods = methods @loc = src @deps = [] if @@entities.has_key?(@name) and @@entities[@name].any?{|e| e.version == @version} loc = @@entities[@name].select{|e| e.version == @version}.first.loc raise Error.new(src), "#{name}: previously defined at #{loc.join(':')}" end raise Error.new(src), "#{name}: entity fields must be a hash!" unless fields.kind_of? Hash raise Error.new(src), "#{name}: entity missing add method!" unless methods.size > 0 @fields = Ditto.symbolize_keys fields nkey = 0 @fields.each do |field, props| symprops = Array(props).select{|p| p.is_a? Symbol} duffprops = symprops - PROPS unless duffprops.empty? raise Error.new(src), "#{name}: unknown properties: '#{duffprops.join(' ,')}'" end nkey += symprops.count(:unique) @deps << field if symprops.include? :related end @@entities[@name] << self end |
Instance Attribute Details
#deps ⇒ Object (readonly)
Returns the value of attribute deps.
21 22 23 |
# File 'lib/ditto/entity.rb', line 21 def deps @deps end |
#fields ⇒ Object (readonly)
Returns the value of attribute fields.
21 22 23 |
# File 'lib/ditto/entity.rb', line 21 def fields @fields end |
#loc ⇒ Object (readonly)
Returns the value of attribute loc.
21 22 23 |
# File 'lib/ditto/entity.rb', line 21 def loc @loc end |
#methods ⇒ Object (readonly)
Returns the value of attribute methods.
21 22 23 |
# File 'lib/ditto/entity.rb', line 21 def methods @methods end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
21 22 23 |
# File 'lib/ditto/entity.rb', line 21 def name @name end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
21 22 23 |
# File 'lib/ditto/entity.rb', line 21 def version @version end |
Class Method Details
.dep_list(name, list, done) ⇒ Object
Compute dependencies recursively build a list in dependency sequence
143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/ditto/entity.rb', line 143 def self.dep_list(name, list, done) raise "circular dependency: #{name}" if done.include? name raise "missing dependency: #{name}" unless @@entities.has_key? name deps = @@entities[name].flat_map {|e| e.deps}.uniq done.push name deps.each do |depname| self.dep_list depname, list, done end done.pop list << name unless list.include? name end |
.find_entity(name, version) ⇒ Object
Given the input data version get the right entity
130 131 132 |
# File 'lib/ditto/entity.rb', line 130 def self.find_entity name, version @@entities[name].sort.first end |
.find_map(entity, type) ⇒ Object
134 135 136 137 138 |
# File 'lib/ditto/entity.rb', line 134 def self.find_map entity, type entity.methods.find do |m| m[0] == type and true end end |
.load_entities(filepath, verbose = 0) ⇒ Object
Load entities required by the instances
102 103 104 105 106 107 108 109 |
# File 'lib/ditto/entity.rb', line 102 def self.load_entities filepath, verbose = 0 puts "loading entities..." if verbose > 0 @@instances.each_key do |name| self.load_from_file File.("#{name}.ditto", filepath) puts "#{name}: #{@@entities[name].inspect}" if verbose > 1 end puts "loaded #{@@entities.size} entities" if verbose > 0 end |
.load_from_file(f) ⇒ Object
Errors discovered in here will be load/syntax errors Stack depth is just empirically determined! TODO WRITE A TEST!
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/ditto/entity.rb', line 61 def self.load_from_file f begin load File.absolute_path(f) return true rescue Ditto::Error raise rescue SyntaxError => se # Includes the failing location raise Error.new(), "#{se.class}: #{se.to_s}" rescue StandardError => le loc = le.backtrace[0].split(':') raise Error.new(loc), "#{f}: #{le.class}: #{le.to_s}" end end |
.load_instances(f, verbose = 0) ⇒ Object
Load data from YAML files into the in-memory representation return number of instances loaded if all OK
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ditto/entity.rb', line 78 def self.load_instances f, verbose = 0 header = nil nent = 0 YAML::load_documents(File.open(f)) do |doc| unless header header = Ditto.symbolize_keys doc puts "header #{header.to_s}" if verbose > 2 version = Gem::Version.new(header[:version]) puts "version: #{version.to_s}" if verbose > 1 next end e = doc.flatten raise Ditto::Error "Entity instance has multiple keys" if e.size != 2 name = e[0].to_sym fields = Ditto.symbolize_keys e[1] puts "#{name}: #{fields.inspect}" if verbose > 1 @@instances[name][version] << fields nent += 1 end return nent end |
.reset ⇒ Object
16 17 18 19 |
# File 'lib/ditto/entity.rb', line 16 def self.reset @@entities.clear @@instances.clear end |
.store_all(verbose = 0) ⇒ Object
Store the instances in dependency order
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/ditto/entity.rb', line 113 def self.store_all verbose = 0 seq = [] @@entities.each_key { |name| self.dep_list(name, seq, []) } puts "dependency sequence: #{seq.inspect}" if verbose > 2 seq.each do |name| @@instances[name].each do |version, instances| entity = self.find_entity name, version map = self.find_map entity, :add instances.each do |instance| puts "store #{name}: #{instance.inspect}" if verbose > 2 map[2].call OpenStruct.new(instance) end end end end |