lib/inat/data/model.rb in inat-get-0.8.0.12 vs lib/inat/data/model.rb in inat-get-0.8.0.13

- old
+ new

@@ -1,16 +1,21 @@ # frozen_string_literal: true require_relative '../app/globals' require_relative 'types/std' -autoload :Entity, 'inat/data/entity' +module INat::Data + autoload :Entity, 'inat/data/entity' +end -class Model +module INat::Data; end - include LogDSL +class INat::Data::Model + include INat::App::Logger::DSL + + # @private class Field attr_reader :model, :name, :type, :id_field def required? @@ -40,20 +45,23 @@ nil end end - class ScalarField < Model::Field + # @private + class ScalarField < Field + using INat::Types::Std + attr_reader :index, :unique, :primary_key def required? @required end def initialize model, name, type, id_field, required, index, unique, primary_key - if Class === type && Entity > type && id_field == nil + if Class === type && INat::Data::Entity > type && id_field == nil id_field = "#{ name }_id".intern end super model, name, type, id_field @required = required @index = index @@ -72,11 +80,11 @@ instance_variable_get("@#{ ni }") end md.define_method "#{ ni }=" do |value| prevalue = instance_variable_get "@#{ ni }" if prevalue != value - debug "ASS: #{ self.id }: #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.name == 'Taxon' + debug "ASS: #{ self.id }: #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.short_name == 'Taxon' instance_variable_set "@#{ ni }", value instance_variable_set "@saved", false end end md.define_method "#{ nm }" do @@ -90,11 +98,11 @@ end end md.define_method "#{ nm }=" do |value| prevalue = instance_variable_get "@#{ ni }" if prevalue != value&.id - debug "ASS: #{ self.id }: #{ nm } / #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.name == 'Taxon' + debug "ASS: #{ self.id }: #{ nm } / #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.short_name == 'Taxon' instance_variable_set "@#{ ni }", value&.id instance_variable_set "@saved", false end end else @@ -103,11 +111,11 @@ end md.define_method "#{ nm }=" do |value| raise TypeError, "Invalid '#{ nm }' value: #{ value.inspect }!", caller unless tp === value || (value == nil && !rq) prevalue = instance_variable_get "@#{ nm }" if prevalue != value - debug "ASS: #{ self.id }: #{ nm } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.name == 'Taxon' + debug "ASS: #{ self.id }: #{ nm } = #{ prevalue.inspect } <=> #{ value.inspect }" if prevalue != nil && self.class.short_name == 'Taxon' instance_variable_set "@#{ nm }", value instance_variable_set "@saved", false end end end @@ -205,12 +213,15 @@ :value end end - class ArrayField < Model::Field + # @private + class ArrayField < Field + using INat::Types::Std + attr_reader :back_field def owned? @owned end @@ -221,11 +232,11 @@ id_field = "#{ name[..-2] }_ids".intern else raise ArgumentError, "Argument 'id_field' is required for name '#{ name }'!", caller[1..] end end - back_field = "#{ model.name.downcase }_id".intern if back_field == nil + back_field = "#{ model.short_name.downcase }_id".intern if back_field == nil super model, name, type, id_field @owned = owned @back_field = back_field end @@ -246,11 +257,11 @@ value&.delete(self.id) value&.prepend 48460 value = value&.sort.uniq end if prevalue != value - debug "ASS: #{ self.id }: #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect } :: #{ caller[..2] }" if prevalue != nil && self.class.name == 'Taxon' + debug "ASS: #{ self.id }: #{ ni } = #{ prevalue.inspect } <=> #{ value.inspect } :: #{ caller[..2] }" if prevalue != nil && self.class.short_name == 'Taxon' instance_variable_set "@#{ ni }", value instance_variable_set "@saved", false end end md.define_method "#{ nm }" do @@ -272,11 +283,11 @@ value.each do |v| raise TypeError, "Invalid #{ nm } value: #{ v.inspect }!", caller unless tp === v end prevalue = instance_variable_get("@#{ nm }") if prevalue&.sort != value&.sort - debug "ASS: #{ self.id }: #{ nm } = #{ prevalue.inspect } <=> #{ value.inspect } :: #{ caller[..2] }" if prevalue != nil && self.class.name == 'Taxon' + debug "ASS: #{ self.id }: #{ nm } = #{ prevalue.inspect } <=> #{ value.inspect } :: #{ caller[..2] }" if prevalue != nil && self.class.short_name == 'Taxon' instance_variable_set "@#{ nm }", value instance_variable_set "@saved", false end end end @@ -290,17 +301,20 @@ @owned end end - class ManyToManyField < Model::ArrayField + # @private + class ManyToManyField < ArrayField + using INat::Types::Std + attr_reader :table_name, :link_field, :index def initialize model, name, type, id_field, owned, table_name, back_field, link_field, index - table_name = "#{ model.name.downcase }_#{ name }".intern if table_name == nil - link_field = "#{ type.name.downcase }_id".intern if link_field == nil + table_name = "#{ model.short_name.downcase }_#{ name }".intern if table_name == nil + link_field = "#{ type.short_name.downcase }_id".intern if link_field == nil super model, name, type, id_field, owned, back_field @table_name = table_name @link_field = link_field @index = index end @@ -325,19 +339,21 @@ :links end end - class OneToManyField < Model::ArrayField + # @private + class OneToManyField < ArrayField def kind :backs end end - class SpecialField < Model::Field + # @private + class SpecialField < Field def initialize model, name, type, &block raise ArgumentError, "Block is required!", caller[1..] unless block_given? super model, name, type, nil @block = block @@ -357,11 +373,12 @@ true end end - class IgnoreField < Model::SpecialField + # @private + class IgnoreField < SpecialField def initialize model, name super model, name, Object do nil end @@ -431,11 +448,19 @@ end result.merge! @fields result.freeze end - private def field name, type: nil, id_field: nil, required: false, index: false, unique: false, primary_key: false + # Defines a new field + # @param [Symbol] name + # @param [Class] type + # @return [void] + # @!macro [attach] field + # @api public + # @!attribute [rw] + # @return [$2] the +$1+ field + def field name, type: nil, id_field: nil, required: false, index: false, unique: false, primary_key: false raise TypeError, "Field name must be a Symbol!", caller unless Symbol === name raise TypeError, "Field type must be a Module!", caller unless Module === type raise TypeError, "Argument 'id_field' must be a Symbol!", caller unless Symbol === id_field || id_field == nil raise TypeError, "Argument 'required' must be a Boolean!", caller unless Boolean === required raise TypeError, "Argument 'index' must be a Boolean!", caller unless Boolean === index @@ -444,13 +469,21 @@ @fields ||= {} @fields[name] = ScalarField::new self, name, type, id_field, required, index, unique, primary_key @fields[name].implement end - private def links name, item_type: nil, ids_field: nil, owned: true, table_name: nil, back_field: nil, link_field: nil, index: false + # Defines a new many-to-many field + # @param [Symbol] name + # @param [Class] item_type + # @return [void] + # @!macro [attach] links + # @api public + # @!attribute [rw] + # @return [Array<$2>] the +$1+ field + def links name, item_type: nil, ids_field: nil, owned: true, table_name: nil, back_field: nil, link_field: nil, index: false raise TypeError, "Field name must be a Symbol!", caller unless Symbol === name - raise TypeError, "Item type must be an Entity subclass!", caller unless Class === item_type && Entity > item_type + raise TypeError, "Item type must be an Entity subclass!", caller unless Class === item_type && INat::Entity > item_type raise TypeError, "Argument 'ids_field' must be a Symbol!", caller unless Symbol === ids_field || ids_field == nil raise TypeError, "Argument 'table_name' must be a Symbol!", caller unless Symbol === table_name || table_name == nil raise TypeError, "Argument 'back_field' must be a Symbol!", caller unless Symbol === back_field || back_field == nil raise TypeError, "Argument 'link_field' must be a Symbol!", caller unless Symbol === link_field || link_field == nil raise TypeError, "Argument 'owned' must be a Boolean!", caller unless Boolean === owned @@ -458,21 +491,37 @@ @fields ||= {} @fields[name] = ManyToManyField::new self, name, item_type, ids_field, owned, table_name, back_field, link_field, index @fields[name].implement end - private def backs name, item_type: nil, ids_field: nil, owned: true, back_field: nil + # Defines a new one-to-many field + # @param [Symbol] name + # @param [Class] item_type + # @return [void] + # @!macro [attach] backs + # @api public + # @!attribute [rw] + # @return [Array<$2>] the +$1+ field + def backs name, item_type: nil, ids_field: nil, owned: true, back_field: nil raise TypeError, "Field name must be a Symbol!", caller unless Symbol === name - raise TypeError, "Item type must be an Entity subclass!", caller unless Class === item_type && Entity > item_type + raise TypeError, "Item type must be an Entity subclass!", caller unless Class === item_type && INat::Entity > item_type raise TypeError, "Argument 'ids_field' must be a Symbol!", caller unless Symbol === ids_field || ids_field == nil raise TypeError, "Argument 'back_field' must be a Symbol!", caller unless Symbol === back_field || back_field == nil raise TypeError, "Argument 'owned' must be a Boolean!", caller unless Boolean === owned @fields ||= {} @fields[name] = OneToManyField::new self, name, item_type, ids_field, owned, back_field @fields[name].implement end - private def block name, type: nil, &block + # Defines a new write-only field + # @param [Symbol] name + # @param [Class] type + # @return [void] + # @!macro [attach] block + # @api public + # @!attribute [w] + # @return [$2] the +$1+ field + def block name, type: nil, &block raise TypeError, "Field name must be a Symbol!", caller unless Symbol === name raise TypeError, "Field type must be a Module!", caller unless Module === type raise ArgumentError, "Block is required!", caller unless block_given? @fields ||= {} @fields[name] = SpecialField::new self, name, type, &block