
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)
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 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) 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 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) 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) 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 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) 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) 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) November 6th, 2009 @ 02:14 AM
Marking as not-applicable due to no response from submitter.
-
Dan Kubb (dkubb) November 6th, 2009 @ 02:15 AM
- State changed from hold to not-applicable
-
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) 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 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) 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 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.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »