Hi all I am indeed a DataMapper newbie and I apologize for that from the
start. I started looking it up because I have a job with an intricate maze
of
legacy databases related to each other and indeed DataMapper seems to fit
the
bill perfectly. However, since I have many models and many different
databases
I was trying to remove the duplication and hide the nitty-gritty of
connections within a module that could extend DataMapper::Resource and be
included in each model a` la DataMapper::Resource. I tried this but it does
not work:
------------------------------------------------------------------------
1 begin
2 require 'ruby-debug'
3 Debugger.start
4 Debugger.settings[:autoeval] = true if
Debugger.respond_to?(:settings)
5 rescue LoadError
6 # ruby-debug wasn't available so neither can the debugging be
7 end
8
9 require 'dm-core'
10 require 'dm-migrations'
11
12 module DmConnector
13
14 def self.included(base)
15 base.extend ClassMethods
16 end
17
18 module ClassMethods
19
20 @@connections = {}
21
22 def connect_to_db(dbname, context)
23 send(:define_method, :default_repository_name) { context }
24 @@connections[context] = DataMapper.setup(context, dbname) unless
@@connections.has_key?(context)
25 DataMapper.auto_upgrade!(context)
26 @@connections[context]
27 end
28
29 DataMapper::Model.append_inclusions self
30
31 end
32
33 end
34
35 DataMapper.setup(:default, 'sqlite::memory:')
36
37 class A
38
39 include DmConnector
40 include DataMapper::Resource
41
42 storage_names[:a_db] = 'a'
43
44 property :id, Serial
45 property :data, Text
46
47 connect_to_db 'sqlite3:a_db.sqlite3', :a_db
48
49 end
50
51 class B
52
53 include DmConnector
54 include DataMapper::Resource
55
56 storage_names[:b_db] = 'b'
57
58 property :id, Serial
59 property :data, Text
60
61 connect_to_db 'sqlite3:b_db.sqlite3', :b_db
62
63 end
64
65 DataMapper.finalize
66
67 puts("A objects count before create: #{A.count}")
68 puts("B objects count before create: #{B.count}")
69
70 a = A.create(:data => 'First A Object')
71 b = B.create(:data => 'First B Object')
72
73 puts("A objects count after one create: #{A.count}")
74 puts("B objects count after one create: #{B.count}")
------------------------------------------------------------------------
Running this program issues:
------------------------------------------------------------------------
/home/nicb/.rvm/gems/ruby-1.9.2-p320@trx_new/gems/dm-do-adapter-1.2.0/lib/dm-do-adapter/adapter.rb:147:in
`execute_reader': no such table: as (DataObjects::SyntaxError)
from
/home/nicb/.rvm/gems/ruby-1.9.2-p320@trx_new/gems/dm-do-adapter-1.2.0/lib/dm-do-adapter/adapter.rb:147:in
`block in read'
from
/home/nicb/.rvm/gems/ruby-1.9.2-p320@trx_new/gems/dm-do-adapter-1.2.0/lib/dm-do-adapter/adapter.rb:276:in
`with_connection'
from
/home/nicb/.rvm/gems/ruby-1.9.2-p320@trx_new/gems/dm-do-adapter-1.2.0/lib/dm-do-adapter/adapter.rb:141:in
`read'
... etc.
from /home/nicb/tmp/test-wrong.rb:67:in `count'
from /home/nicb/tmp/test-wrong.rb:67:in `<main>'
------------------------------------------------------------------------
which is related to the fact that the :default_repository_name method
never gets overridden by the actual per-database context method (so the
"default" method actually returns a wrongly-mangled table name).
The next bit of code works:
------------------------------------------------------------------------
1 begin
2 require 'ruby-debug'
3 Debugger.start
4 Debugger.settings[:autoeval] = true if
Debugger.respond_to?(:settings)
5 rescue LoadError
6 # ruby-debug wasn't available so neither can the debugging be
7 end
8
9 require 'dm-core'
10 require 'dm-migrations'
11
12 module DmConnector
13
14 def self.included(base)
15 base.extend ClassMethods
16 end
17
18 module ClassMethods
19
20 @@connections = {}
21
22 def connect_to_db(dbname, context)
23 @@connections[context] = DataMapper.setup(context, dbname)
unless @@connections.has_key?(context)
24 DataMapper.auto_upgrade!(context)
25 @@connections[context]
26 end
27
28 end
29
30 end
31
32 DataMapper.setup(:default, 'sqlite::memory:')
33
34 class A
35
36 include DmConnector
37 include DataMapper::Resource
38
39 def self.default_repository_name
40 :a_db
41 end
42
43 storage_names[:a_db] = 'a'
44
45 property :id, Serial 46 property :data, Text 47 48 connect_to_db
'sqlite3:a_db.sqlite3', :a_db 49 50 end 51 52 class B 53 54 include
DmConnector 55 include DataMapper::Resource 56 57 def
self.default_repository_name 58 :b_db 59 end 60 61 storage_names[:b_db] =
'b' 62 63 property :id, Serial 64 property :data, Text 65 66 connect_to_db
'sqlite3:b_db.sqlite3', :b_db 67 68 end 69 70 DataMapper.finalize 71 72
puts("A objects count before create: #{A.count}") 73 puts("B objects count
before create: #{B.count}") 74 75 a = A.create(:data => 'First A Object')
76 b = B.create(:data => 'First B Object') 77 78 puts("A objects count
after one create: #{A.count}") 79 puts("B objects count after one create:
#{B.count}")
------------------------------------------------------------------------
but it involves way too many repetitions to be acceptable as serious code.
Needless to say I've been looking wide and large if there is already a
plugin or something that that would do the job for me, but to no avail.
Also, using DataMapper::Model.append_inclusions does not solve the problem.
What am I doing wrong? Can someone help please? Thank you for all the work
Nicola
--
You received this message because you are subscribed to the Google Groups
"DataMapper" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/datamapper/-/a4G1G_ra1A4J.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/datamapper?hl=en.