#1009 ✓not-applicable
deepfryed

dm-constraints does not handle multiple repositories correctly

Reported by deepfryed | August 15th, 2009 @ 05:56 PM

dm-constraints caches repository_name and hence causes an error when trying to create constraints for models that default to different repositories

e.g.

require 'rubygems'
require 'dm-core'
require 'dm-constraints'

DataMapper.setup(:default, { :adapter => :mysql, :database => 'db_1', :username => 'root', :host => 'localhost' })
DataMapper.setup(:db_2, { :adapter => :mysql, :database => 'db_2', :username => 'root', :host => 'localhost' })
[:db_1, :db_2].each do |db| mysql -uroot -e "drop database #{db}" mysql -uroot -e "create database #{db}" end

class Author
include DataMapper::Resource property :id, Serial property :name, String has n, :books end

class Book

include DataMapper::Resource
property :id, Serial
property :name, String
property :author_id, Integer
belongs_to :author

end

module News class Writer

include DataMapper::Resource
property :id, Serial
property :name, String
has n, :articles, :class_name => 'News::Article', :child_key => [ :writer_id ]
def self.default_repository_name

:db_2

end

end

class Article

include DataMapper::Resource
property :id, Serial
property :name, String
property :writer_id, Integer
belongs_to :writer, :class_name => 'News::Writer', :child_key => [ :writer_id ]
def self.default_repository_name
  :db_2
end

end end

::DataMapper.auto_migrate!

the following change fixes this issue

--- a/lib/dm-constraints/data_objects_adapter.rb +++ b/lib/dm-constraints/data_objects_adapter.rb @@ -170,7 +170,7 @@ module DataMapper

       def auto_migrate_constraints_down(repository_name, *descendants)
         descendants = DataMapper::Resource.descendants.to_a if descendants.empty?
         descendants.each do |model|
  •        repository_name ||= model.repository(repository_name).name
    
  •        repository_name = model.repository(nil).name
           if model.storage_exists?(repository_name)
             adapter = model.repository(repository_name).adapter
             next unless adapter.respond_to?(:destroy_constraints_statements)
    
    @@ -183,7 +183,7 @@ module DataMapper
       def auto_migrate_constraints_up(retval, repository_name, *descendants)
         descendants = DataMapper::Resource.descendants.to_a if descendants.empty?
         descendants.each do |model|
    
  •        repository_name ||= model.repository(repository_name).name
    
  •        repository_name = model.repository(nil).name
           adapter = model.repository(repository_name).adapter
           next unless adapter.respond_to?(:create_constraints_statements)
           statements = adapter.create_constraints_statements(repository_name, model)
    

Comments and changes to this ticket

  • deepfryed

    deepfryed August 15th, 2009 @ 06:01 PM

    apologies for being a moron and forgetting to format properly, patch formatted properly

    --- a/lib/dm-constraints/data_objects_adapter.rb
    +++ b/lib/dm-constraints/data_objects_adapter.rb
    @@ -170,7 +170,7 @@ module DataMapper
               def auto_migrate_constraints_down(repository_name, *descendants)
                 descendants = DataMapper::Resource.descendants.to_a if descendants.empty?
                 descendants.each do |model|
    -              repository_name ||= model.repository(repository_name).name
    +              repository_name = model.repository(nil).name
                   if model.storage_exists?(repository_name)
                     adapter = model.repository(repository_name).adapter
                     next unless adapter.respond_to?(:destroy_constraints_statements)
    @@ -183,7 +183,7 @@ module DataMapper
               def auto_migrate_constraints_up(retval, repository_name, *descendants)
                 descendants = DataMapper::Resource.descendants.to_a if descendants.empty?
                 descendants.each do |model|
    -              repository_name ||= model.repository(repository_name).name
    +              repository_name = model.repository(nil).name
                   adapter = model.repository(repository_name).adapter
                   next unless adapter.respond_to?(:create_constraints_statements)
                   statements = adapter.create_constraints_statements(repository_name, model)
    
  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) August 15th, 2009 @ 07:38 PM

    • Assigned user cleared.
    • State changed from “new” to “unconfirmed”

    @deepfryed: Can you test our dm-constraints in the 'next' branch and see if it resolves your issue?

    NOTE: You'll also need the "next" branch versuion of extlib, dm-core, data_objects and do_mysql.

  • deepfryed

    deepfryed August 16th, 2009 @ 04:57 AM

    I seem to have other issues with dm-core/next & dm-more/next

    the constraints are not being created because Integer type in dm defaults to
    INT(11) data type in mysql and Serial defaults to INT(10) unsigned
    resulting in an error when FKs are created (type mismatch)

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) August 16th, 2009 @ 11:56 AM

    deepfryed: Good catch. I recently updated dm-core to use unsigned INT(10) for Serial by default, but I forgot to update the FK inference rules to copy the min/max values from the PK.

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) August 16th, 2009 @ 12:01 PM

    deepfryed: I just committed a fix to dm-core that copies the min/max to any inferred FKs so the type mismatch issue should be resolved.

  • deepfryed

    deepfryed August 16th, 2009 @ 03:18 PM

    works fine if the models are in the same repository, once i change the default_repository_name, throws an error

    /local_gems/gems/dm-core-0.10.0/lib/dm-core/model.rb:714:in `assert_valid': Writer must have at least one property or many to one relationship to be valid (DataMapper::IncompleteModelError)
            from /local_gems/gems/dm-core-0.10.0/lib/dm-core/migrations.rb:1217:in `auto_migrate_down!'
            from /local_gems/gems/dm-core-0.10.0/lib/dm-core/migrations.rb:51:in `send'
            from /local_gems/gems/dm-core-0.10.0/lib/dm-core/migrations.rb:51:in `repository_execute'
            from /local_gems/gems/dm-core-0.10.0/lib/dm-core/model/descendant_set.rb:35:in `each'
            from /local_gems/gems/dm-core-0.10.0/lib/dm-core/model/descendant_set.rb:35:in `each'
            from /local_gems/gems/dm-core-0.10.0/lib/dm-core/migrations.rb:50:in `repository_execute'
            from /local_gems/gems/dm-core-0.10.0/lib/dm-core/migrations.rb:38:in `auto_migrate_down_without_constraints!'
            from /local_gems/gems/dm-constraints-0.10.0/lib/dm-constraints/migrations.rb:18:in `auto_migrate_down!'
            from /local_gems/gems/dm-core-0.10.0/lib/dm-core/migrations.rb:23:in `auto_migrate!'
            from dm_constraints_check.rb:53
    
  • Martin Gamsjaeger (snusnu)

    Martin Gamsjaeger (snusnu) August 24th, 2009 @ 09:21 PM

    deepfryed,

    Be sure to checkout http://alfred.datamapper.org/posts/10 and http://alfred.datamapper.org/posts/11 . If these links don't help, could you pastie a standalone script that reproduces the error you get?

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) October 7th, 2009 @ 12:45 PM

    • State changed from “unconfirmed” to “hold”

    Marking this as "on hold" until deepfryed provides a stand-alone script that reproduces the problem.

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) November 6th, 2009 @ 02:14 AM

    Marking as not-applicable due to no response from submitter.

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) November 6th, 2009 @ 02:15 AM

    • State changed from “hold” to “not-applicable”
  • deepfryed

    deepfryed November 6th, 2009 @ 04:21 PM

    complete forgot about this one. apologies. i'll see if i can replicate this again

  • Dan Kubb (dkubb)

    Dan Kubb (dkubb) November 6th, 2009 @ 09:20 PM

    @deepfryed: No worries. I just like to close stuff out when there's no response after a month or so. It only makes sense to focus on the tickets that are causing the people the most grief, and if there's no response for further info we have to assume it's either fixed, or worked-around, or not really causing a problem anymore.

    Once you can provide a way to reproduce this ticket, I will reopen it.

  • deepfryed

    deepfryed November 7th, 2009 @ 05:20 AM

    tried it with dm-core/master, dm-more/master and still having the same problem with dm-constraints as mysql serial types are being defined as INT(10) and the Integer types defaulting to INT(11)

    standalone example at http://pastie.org/687735

  • Martin Gamsjaeger (snusnu)

    Martin Gamsjaeger (snusnu) November 7th, 2009 @ 09:22 AM

    deepfryed,

    While I don't immediately see how the problem described in your latest pastie relates to the original ticket title concerning multiple repositories, your latest issue can be solved easily. The #belongs_to method generates an INT(10) UNSIGNED property under the hood (on mysql at least). To force a matching FK property if you specify the property yourself too, you would need to define it like below, to make sure it is INT(10) UNSIGNED too.

      property :author_id, Integer, :min => 0
    

    If you don't specify the property explicitly but instead only rely on #belongs_to to generate it for you, everything should work out of the box.

    HTH

  • deepfryed

    deepfryed November 7th, 2009 @ 12:45 PM

    this was something i ran into along the way :)

    specifying :min => 0 solves the problem, thanks !

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Attachments

Pages