view · edit · sidebar · attach · print · history

20120227-check-accessor-class-ActiveAgent-AtcClass-Sequence-fix-ATCOverview-error-oddb_org

<< Masa.20120228-check-accessor-Package-Registration-check-parallel-runs-oddb_org | Index | Masa.20120224-fix-migel-view-atc-overview-oddb_org-drop-crawler-request-sbsm >>


  1. Fix errors (ATC overview) oddb.org
  2. Check accessor class oddb.org
  3. Test all error url locally

Commits
  1. Check accessor classes in ActiveAgent when it is updated. If the class of argument is different from the expected class, it refueses to update the accessor variable and TypeError happens. (oddb.org)
  2. Check accessor classes in AtcClass when it is updated. But the class of element in @sequences and @descriptions is not checked. (oddb.org)
  3. Fix NoMethodError undefined method [] for nil:NilClass at src/view/drugs/resultlist.rb:296 (oddb.org)
  4. Check accessor classes of Sequence (oddb.org)

Fix errors (ATC overview) oddb.org

Error

error in SBSM::Session#to_html: /de/gcc/search/search_query/Mezereum-Homaccord/search_type/st_sequence/code/D11AX/currency/USD
NoMethodError
undefined method `[]' for nil:NilClass
/home/masa/ywesee/oddb.org/src/view/drugs/resultlist.rb:296:in `compose_list'
/usr/local/lib/ruby/gems/1.9.1/gems/htmlgrid-1.0.5/lib/htmlgrid/list.rb:54:in `compose'
/usr/local/lib/ruby/gems/1.9.1/gems/htmlgrid-1.0.5/lib/htmlgrid/composite.rb:56:in `init'
/usr/local/lib/ruby/gems/1.9.1/gems/htmlgrid-1.0.5/lib/htmlgrid/list.rb:129:in `init'

Commit

Check accessor class oddb.org

Experiment

  • src/model/package.rb
    class PackageCommon
    ....
      def define_check_class_method(accessor, klass)
        define_method("#{accessor.to_s}=") do |arg|
          #if arg.is_a?(ODDB::Sequence)
          if arg.class.to_s == klass.to_s
            @sequence = arg
          else
            arg_class = arg.class
            arg = if arg.respond_to?(:to_s)
                    arg.to_s[0,10]
                  end
            raise TypeError.new("'#{arg.to_s}'(#{arg_class}) should be #{klass}")
          end
        end
      end
    end
    ...
    check_classes = {:sequence => 'ODDB::Sequence'}
    check_classes.each do |accessor, klass|
      define_check_class_method accessor, klass
    end

Run

  • bin/admin
  • fails in updating @sequence
ch.oddb> update(ODDB::Package.find_by_pharmacode('223332').pointer, {:sequence => 'utf-8'}, :admin)
-> 'utf-8'(String) should be a ODDB::Sequence
ch.oddb> registration('31706').sequence('02').odba_id
-> 73749
ch.oddb> registration('31706').sequence('01').odba_id
-> 73748
ch.oddb> ODDB::Package.find_by_pharmacode('223332').sequence.odba_id
-> 73748
ch.oddb> seq = registration('31706').sequence('02'); update(ODDB::Package.find_by_pharmacode('223332').pointer, {:sequence => seq}, :admin)
-> #<ODDB::Package:0x00000001bcbbe0>
ch.oddb> ODDB::Package.find_by_pharmacode('223332').sequence.odba_id
-> 73749

Next

  • Check the classes of ActiveAgent accessors (Zusammensetzung) one by one

ActiveAgent class

  • Sequence@compositions (Array of Composition)
  • Composition@active_agents (Array of ActiveAgent)
  • Object relation: Sequence 1-* Composition 1-* ActiveAgent
  • Sequence#active_agents: this method accesses to all the active_agents belonging to the sequence

Check all accessor class

  • src/model/activeagent.rb
    attr_accessor :substance
    attr_accessor :chemical_substance, :equivalent_substance
    attr_accessor :dose, :chemical_dose, :equivalent_dose, :sequence
    attr_accessor :spagyric_dose, :spagyric_type, :composition

Experiment

  • bin/admin
ch.oddb> registrations.values.map{|reg| reg.sequences.values.map{|seq| seq.active_agents.map{|aa| aa.substance.class}}}.flatten.uniq
-> [ODDB::Substance]
  • src/util/oddbapp.rb
  def check_active_agent_class
    methods = [:substance, :chemical_substance, :equivalent_substance, :dose, :chemical_dose, :equivalent_dose, :sequence]
    open("/home/masa/work/active_agent_class.dat","w") do |out|
      methods.each do |method|
        classes = registrations.values.map do |reg|
          reg.sequences.values.map do |seq|
            seq.active_agents.map do |aa|
              aa.send(method).class
            end
          end
        end.flatten.uniq
        out.print method, ": ", classes.join(","), "\n"
      end
    end
  end

Result

:substance => ODDB::Substance
:chemical_substance => NilClass,ODDB::Substance
:equivalent_substance => NilClass,ODDB::Substance
:dose => ODDB::Dose,NilClass
:chemical_dose => NilClass,ODDB::Dose
:equivalent_dose => NilClass,ODDB::Dose
:sequence => ODDB::Sequence

Commit

Next

  • Check accessors of
    1. AtcClass
    2. Sequence class

AtcClass

  • bin/oddbd
masa@masa ~/ywesee/oddb.org $ ruby -I . -rcheck_accessor bin/oddbd
ch.oddb> ODDB::AtcClass.attr_writers
-> [:code, :sequences, :descriptions]

Check accessor classes

  • bin/oddb
masa@masa ~/ywesee/oddb.org $ ruby -I . -rcheck_class bin/oddbd 
ch.oddb> check_atcclass_accessor_class

Result

:code => "String",
:sequences => "Array",
:descriptions => "ODDB::SimpleLanguage::Descriptions",

Commit

Note (for development)

  • This check method checks only the updating an instance variable with '='
  • If an instance variable is Array or Hash and its attribute is 'attr_reader', then it is possible to update the element without class check.
  • In the case of AtcClass, the element of @sequences and @descriptions can be updated without class check. (@sequences is an Array and Descriptions class inherits Hash)

Sequence

  • bin/oddbd
masa@masa ~/ywesee/oddb.org $ ruby -I . -rcheck_accessor bin/oddbd
  • bin/admin
ch.oddb> ODDB::SequenceCommon.attr_writers
-> [:registration, :atc_class, :export_flag, :patinfo, :pdf_patinfo, :atc_request_time, :deactivate_patinfo, :sequence_date, :activate_patinfo, :composition_text, :dose, :inactive_date]
  • bin/oddbd
masa@masa ~/ywesee/oddb.org $ ruby -I . -rcheck_class bin/oddbd 
ch.oddb> check_sequence_accessor_class

Result

:registration => "ODDB::Registration",
:atc_class => "ODDB::AtcClass,NilClass",
:export_flag => "FalseClass,TrueClass,NilClass",
:patinfo => "NilClass,ODDB::Patinfo",
:pdf_patinfo => "NilClass,String",
:atc_request_time => "NilClass,Time",
:deactivate_patinfo => "NilClass,Date",
:sequence_date => "NilClass,Date",
:activate_patinfo => "NilClass,Date",
:composition_text => "NilClass,String",
:dose => "ODDB::Dose,NilClass",
:inactive_date => "NilClass",

Commit

Check Array and Hash element class

Note

  • It is needed to define a new method (instance-specific method) to check the element class of array to an instance variable after the object creation
  • But the most of initialize method is NOT called after the object is saved in the database because it is marshal loaded when oddbd boots
  • Question is, 'when should the element check method be defined? (except for its initialize method)'

Temporary conclusion

  • It is not so easy to add a new instance-specific method to check the element class of Array or Hash
  • For the moment, we should stop adding the check method of element of Array instance variable

Test all error url locally

Test

$ sh batch.sh

Result

  • No error comes

Note

  • As for the error log on 20120227, I can see often the following objects replaced somehow
    1. Sequence@packages (also the element)
    2. Package@parts (also the element)
view · edit · sidebar · attach · print · history
Page last modified on February 28, 2012, at 07:18 AM