dm-reflection 0.11.0 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -12,6 +12,7 @@ begin
12
12
  gem.homepage = "http://github.com/yogo/dm-reflection"
13
13
  gem.authors = ["Martin Gamsjaeger (snusnu), Yogo Team"]
14
14
  gem.add_dependency('dm-core', '~> 0.10.2')
15
+ gem.add_dependency('activesupport')
15
16
  gem.add_development_dependency('rspec', ['~> 1.3'])
16
17
  gem.add_development_dependency('yard', ['~> 0.5'])
17
18
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.0
1
+ 0.11.1
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dm-reflection}
8
- s.version = "0.11.0"
8
+ s.version = "0.11.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Martin Gamsjaeger (snusnu), Yogo Team"]
12
- s.date = %q{2010-06-09}
12
+ s.date = %q{2010-06-24}
13
13
  s.description = %q{Generates datamapper models from existing database schemas and export them to files}
14
14
  s.email = %q{irjudson [a] gmail [d] com}
15
15
  s.extra_rdoc_files = [
@@ -62,15 +62,18 @@ Gem::Specification.new do |s|
62
62
 
63
63
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
64
64
  s.add_runtime_dependency(%q<dm-core>, ["~> 0.10.2"])
65
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
65
66
  s.add_development_dependency(%q<rspec>, ["~> 1.3"])
66
67
  s.add_development_dependency(%q<yard>, ["~> 0.5"])
67
68
  else
68
69
  s.add_dependency(%q<dm-core>, ["~> 0.10.2"])
70
+ s.add_dependency(%q<activesupport>, [">= 0"])
69
71
  s.add_dependency(%q<rspec>, ["~> 1.3"])
70
72
  s.add_dependency(%q<yard>, ["~> 0.5"])
71
73
  end
72
74
  else
73
75
  s.add_dependency(%q<dm-core>, ["~> 0.10.2"])
76
+ s.add_dependency(%q<activesupport>, [">= 0"])
74
77
  s.add_dependency(%q<rspec>, ["~> 1.3"])
75
78
  s.add_dependency(%q<yard>, ["~> 0.5"])
76
79
  end
@@ -1,3 +1,4 @@
1
+ require 'activesupport'
1
2
  require 'dm-reflection/reflection'
2
3
  require 'dm-reflection/adapters/sqlite3'
3
4
  require 'dm-reflection/adapters/persevere'
@@ -118,28 +118,36 @@ module DataMapper
118
118
  end
119
119
 
120
120
  if join_table
121
- attribute[:type] = DataMapper::Associations::Relationship
121
+ attribute[:type] = :many_to_many
122
+ attribute.delete(:default)
123
+ attribute.delete(:key)
124
+ attribute.delete(:required)
122
125
  attribute[:relationship] = {
123
126
  # M:M requires we wire things a bit differently and remove the join model
124
127
  :many_to_many => true,
125
- :parent => Extlib::Inflection.classify(left_table_name),
126
- :child => Extlib::Inflection.classify(right_table_name),
128
+ :parent_name => left_table_name.pluralize,
129
+ :parent => ActiveSupport::Inflector.classify(left_table_name),
130
+ :child_name => right_table_name.pluralize,
131
+ :child => ActiveSupport::Inflector.classify(right_table_name),
127
132
  # When we can detect more from the database we can optimize this
128
133
  :cardinality => Infinity,
129
134
  :bidirectional => true }
130
135
  return [attribute]
131
136
  elsif type == Integer && field_name[-3,3] == "_id"
132
- # This is a foriegn key. So this model belongs_to the other (_id) one.
133
- # Add a special set of values and flag this as a relationship so the reflection code
134
- # can rebuild the relationship when it's building the model.
135
- attribute[:type] = DataMapper::Associations::Relationship
136
- attribute[:relationship] = {
137
- :many_to_many => false,
138
- :parent => Extlib::Inflection.classify(field_name[0..-4]),
139
- :child => Extlib::Inflection.classify(table),
140
- # When we can detect more from the database we can optimize this
141
- :cardinality => Infinity,
142
- :bidirectional => true }
137
+ attribute.delete(:default)
138
+ attribute.delete(:key)
139
+ attribute.delete(:required)
140
+ fixed_field_name = field_name[0..-4]
141
+ unless table == ActiveSupport::Inflector.tableize(fixed_field_name)
142
+ attribute[:type] = :belongs_to
143
+ attribute[:name] = ActiveSupport::Inflector.singularize(fixed_field_name)
144
+ attribute[:model] = ActiveSupport::Inflector.classify(attribute[:name])
145
+ attribute[:other_side] = {
146
+ :name => ActiveSupport::Inflector.pluralize(table),
147
+ :model => ActiveSupport::Inflector.camelize(table),
148
+ # When we can detect more from the database we can optimize this
149
+ :cardinality => Infinity }
150
+ end
143
151
  end
144
152
  attribute
145
153
  end
@@ -16,13 +16,14 @@ module DataMapper
16
16
  chainable do
17
17
  def get_type(db_type)
18
18
 
19
- return :has_one_relation if db_type.has_key?("$ref")
19
+ # return :has_one_relation if db_type.has_key?("$ref")
20
20
 
21
21
  type = db_type['type']
22
22
  format = db_type['format']
23
23
 
24
24
  case type
25
- when 'array' then :has_many_relation
25
+ when Hash then :belongs_to
26
+ when 'array' then :has_n
26
27
  when 'serial' then DataMapper::Types::Serial
27
28
  when 'integer' then Integer
28
29
  # when 'number' then BigDecimal
@@ -66,30 +67,33 @@ module DataMapper
66
67
  def get_properties(table)
67
68
  attributes = Array.new
68
69
  schema = self.get_schema(table)[0]
70
+ if schema.has_key?('properties')
71
+
69
72
  schema['properties'].each_pair do |key, value|
70
73
  type = get_type(value)
74
+ debugger if type.nil?
75
+ name = key.sub("#{value['prefix']}#{value['separator']}", "")
76
+ attribute = { :name => name }
71
77
 
72
- attribute = { :name => key }
73
-
74
- if type == :has_one_relation
75
- # Has one
76
- # Retrieve the other side to determine the cardinality
77
- other_table = [table.split('/')[0..-2], value['$ref']].join("/")
78
- other_schema = self.get_schema(other_table)[0]
79
-
80
- elsif type == :has_many_relation
81
- # Has many
82
- # Retrieve the other side to determine the cardinality
83
- other_table = [table.split('/')[0..-2], value['items']['$ref']].join("/")
84
- other_schema = self.get_schema(other_table)[0]
85
-
78
+ if type == :belongs_to
79
+ # belongs_to
80
+ attribute[:type] = :belongs_to
81
+ attribute[:prefix] = value['prefix'] if value.has_key?('prefix')
82
+ elsif type == :has_n
83
+ attribute[:type] = :has_n
84
+ other_table = [table.split('/')[0..-2], value['items']['$ref']].flatten.join("/")
85
+ other_class = other_table.camelize
86
+ attribute[:cardinality] = Infinity
87
+ attribute[:model] = other_class
88
+ attribute.merge!({:prefix => value['prefix']}) if value.has_key?('prefix')
86
89
  else
87
90
  attribute.merge!({ :type => type, :required => !value.delete('optional'), :key => value.has_key?('index') && value.delete('index') }) unless attribute[:type] == DataMapper::Types::Serial
88
91
  ['type', 'format', 'unique', 'index', 'items'].each { |key| value.delete(key) }
89
92
  value.keys.each { |key| value[key.to_sym] = value[key]; value.delete(key) }
90
93
  attribute.merge!(value)
91
- attributes << attribute
92
94
  end
95
+ attributes << attribute
96
+ end
93
97
  end
94
98
  return attributes
95
99
  end
@@ -99,7 +103,7 @@ module DataMapper
99
103
 
100
104
  # Turns 'class_path/class' into 'ClassPath::Class
101
105
  def derive_relationship_model(input)
102
- input.match(/(Class)?\/([a-z\-\/\_]+)$/)[-1].split('/').map{|i| Extlib::Inflection.classify(i) }.join("::")
106
+ input.match(/(Class)?\/([a-z\-\/\_]+)$/)[-1].split('/').map{|i| ActiveSupport::Inflector.classify(i) }.join("::")
103
107
  end
104
108
 
105
109
  end # module PersevereAdapter
@@ -124,8 +124,8 @@ module DataMapper
124
124
  # can rebuild the relationship when it's building the model.
125
125
  attribute[:type] = DataMapper::Associations::Relationship
126
126
  attribute[:relationship] = {
127
- :parent => Extlib::Inflection.classify(field_name[0..-4]),
128
- :child => Extlib::Inflection.classify(table),
127
+ :parent => ActiveSupport::Inflector.classify(field_name[0..-4]),
128
+ :child => ActiveSupport::Inflector.classify(table),
129
129
  # When we can detect more from the database we can optimize this
130
130
  :cardinality => Infinity,
131
131
  :bidirectional => true }
@@ -83,8 +83,8 @@ module DataMapper
83
83
  # can rebuild the relationship when it's building the model.
84
84
  attribute[:type] = DataMapper::Associations::Relationship
85
85
  attribute[:relationship] = {
86
- :parent => Extlib::Inflection.classify(field_name[0..-4]),
87
- :child => Extlib::Inflection.classify(table),
86
+ :parent => ActiveSupport::Inflector.classify(field_name[0..-4]),
87
+ :child => ActiveSupport::Inflector.classify(table),
88
88
  # When we can detect more from the database we can optimize this
89
89
  :cardinality => Infinity,
90
90
  :bidirectional => true }
@@ -169,7 +169,7 @@ module DataMapper
169
169
  end
170
170
 
171
171
  def type
172
- Extlib::Inflection.demodulize(backend.type)
172
+ ActiveSupport::Inflector.demodulize(backend.type)
173
173
  end
174
174
 
175
175
 
@@ -255,7 +255,7 @@ module DataMapper
255
255
  def prioritized_options
256
256
  option_priorities.inject([]) do |memo, name|
257
257
  if name == :through && through = backend_options[:through]
258
- value = through.is_a?(Symbol) ? through : Extlib::Inflection.demodulize(through)
258
+ value = through.is_a?(Symbol) ? through : ActiveSupport::Inflector.demodulize(through)
259
259
  memo << [ :through, value ]
260
260
  end
261
261
  memo
@@ -14,7 +14,7 @@ module DataMapper
14
14
 
15
15
  adapter.get_storage_names.each do |storage_name|
16
16
  namespace_parts = storage_name.split(separator).map do |part|
17
- Extlib::Inflection.classify(part)
17
+ ActiveSupport::Inflector.classify(part)
18
18
  end
19
19
 
20
20
  model_name = namespace_parts.pop
@@ -39,30 +39,40 @@ module DataMapper
39
39
  RUBY
40
40
  end
41
41
  end
42
-
43
- models[model_name] = namespace.const_set(model_name, anonymous_model)
42
+
43
+ full_name = namespace_parts.length > 0 ? [namespace_parts, model_name].join('::') : model_name
44
+ models[full_name] = namespace.const_set(model_name, anonymous_model)
44
45
  end
45
46
 
46
47
  join_models = Array.new
47
48
 
48
49
  models.each do |model_name, model|
49
50
  adapter.get_properties(model.storage_name).each do |attribute|
50
- if attribute[:type] == DataMapper::Associations::Relationship
51
- parent = models[attribute[:relationship][:parent]]
52
- child = models[attribute[:relationship][:child]]
53
- if parent.nil? or child.nil?
54
- puts "Reflection Relationship: P: #{parent.inspect} C: #{child.inspect} A: #{attribute[:relationship].inspect}"
55
- end
56
- if attribute[:relationship][:many_to_many]
57
- parent.has(attribute[:relationship][:cardinality], child.name.tableize.pluralize.downcase.to_sym, :through => DataMapper::Resource, :model => child)
58
- child.has(attribute[:relationship][:cardinality], parent.name.tableize.pluralize.downcase.to_sym, :through => DataMapper::Resource, :model => parent)
59
- # Remove join model
60
- join_models << model_name
61
- else
62
- child.belongs_to(parent.name.tableize.downcase.to_sym, :model => parent)
63
- if attribute[:relationship][:bidirectional]
64
- parent.has(attribute[:relationship][:cardinality], child.name.tableize.pluralize.downcase.to_sym, :model => child)
65
- end
51
+ if attribute[:type] == :many_to_many
52
+ attribute.delete(:type)
53
+ attribute.delete(:name)
54
+ relationship = attribute.delete(:relationship)
55
+ parent = models[relationship.delete(:parent)]
56
+ child = models[relationship.delete(:child)]
57
+ cardinality = relationship.delete(:cardinality)
58
+ parent.has(cardinality, relationship[:child_name].to_sym, attribute.merge({:through => DataMapper::Resource, :model => child}))
59
+ child.has(cardinality, relationship[:parent_name].to_sym, attribute.merge({:through => DataMapper::Resource, :model => parent}))
60
+ join_models << model_name
61
+ elsif attribute[:type] == :has_n
62
+ attribute.delete(:type)
63
+ model.has(attribute.delete(:cardinality), attribute.delete(:name).to_sym, attribute)
64
+ elsif attribute[:type] == :belongs_to
65
+ attribute.delete(:type)
66
+ other_side = attribute.delete(:other_side)
67
+ name = attribute.delete(:name)
68
+ # puts "#{model.name}.belongs_to(#{name}, #{attribute.inspect})"
69
+ model.belongs_to(name.to_sym, attribute.dup)
70
+ unless other_side.nil?
71
+ other_name = other_side.delete(:name)
72
+ cardinality = other_side.delete(:cardinality)
73
+ other_side[:model] = ActiveSupport::Inflector.singularize(model)
74
+ # puts "#{models[attribute[:model]]}.has(#{cardinality}, #{other_name}, #{other_side.inspect})"
75
+ models[attribute[:model]].has(cardinality, other_name.to_sym, other_side)
66
76
  end
67
77
  else
68
78
  attribute.delete_if { |k,v| v.nil? }
@@ -46,19 +46,19 @@ if ENV['ADAPTER'] == 'persevere'
46
46
  :PostComment => POST_COMMENT,
47
47
  }
48
48
 
49
- @models.each_key { |model| Extlib::Inflection.constantize(model.to_s).auto_migrate! }
50
- @models.each_key { |model| remove_model_from_memory( Extlib::Inflection.constantize(model.to_s) ) }
49
+ @models.keys.reverse.each { |model| ActiveSupport::Inflector.constantize(model.to_s).auto_migrate! }
50
+ @models.keys.reverse.each { |model| remove_model_from_memory( ActiveSupport::Inflector.constantize(model.to_s) ) }
51
51
  end
52
52
 
53
53
  after(:each) do
54
- @models.each_key do |model_name|
54
+ @models.keys.reverse.each do |model_name|
55
55
  next unless Object.const_defined?(model_name)
56
- model = Extlib::Inflection.constantize(model_name.to_s)
56
+ model = ActiveSupport::Inflector.constantize(model_name.to_s)
57
57
  remove_model_from_memory(model)
58
58
  end
59
- @models.each_key do |model_name|
59
+ @models.keys.reverse.each do |model_name|
60
60
  next unless Object.const_defined?(model_name)
61
- model = Extlib::Inflection.constantize(model_name.to_s)
61
+ model = ActiveSupport::Inflector.constantize(model_name.to_s)
62
62
  remove_model_from_memory(model)
63
63
  end
64
64
  end
@@ -84,15 +84,15 @@ describe 'The DataMapper reflection module' do
84
84
  :Parent => PARENT,
85
85
  :Child => CHILD
86
86
  }
87
-
88
- @models.each_key { |model| Extlib::Inflection.constantize(model.to_s).auto_migrate! }
89
- @models.each_key { |model| remove_model_from_memory( Extlib::Inflection.constantize(model.to_s) ) }
87
+
88
+ @models.keys.reverse.each { |model| ActiveSupport::Inflector.constantize(model.to_s).auto_migrate! }
89
+ @models.keys.reverse.each { |model| remove_model_from_memory( ActiveSupport::Inflector.constantize(model.to_s) ) }
90
90
  end
91
91
 
92
92
  after(:each) do
93
- @models.each_key do |model_name|
93
+ @models.keys.reverse.each do |model_name|
94
94
  next unless Object.const_defined?(model_name)
95
- model = Extlib::Inflection.constantize(model_name.to_s)
95
+ model = ActiveSupport::Inflector.constantize(model_name.to_s)
96
96
  model.auto_migrate_down!
97
97
  remove_model_from_memory(model)
98
98
  end
@@ -101,12 +101,12 @@ describe 'The DataMapper reflection module' do
101
101
  describe 'repository(:name).reflect' do
102
102
  it 'should reflect all the models in a repository' do
103
103
  # Reflect the models back into memory.
104
- DataMapper::Reflection.reflect(:default)
104
+ results = DataMapper::Reflection.reflect(:default)
105
105
 
106
106
  # Iterate through each model in memory and verify the source is the same as the original.
107
107
  # using model.to_ruby
108
108
  @models.each_pair do |model_name, source|
109
- model = Extlib::Inflection.constantize(model_name.to_s)
109
+ model = ActiveSupport::Inflector.constantize(model_name.to_s)
110
110
  reflected_source = model.to_ruby
111
111
  reflected_source.should == source
112
112
  end
@@ -119,7 +119,7 @@ describe 'The DataMapper reflection module' do
119
119
  DataMapper::Reflection.reflect(:default)
120
120
 
121
121
  @models.each_key do |model_name|
122
- model = Extlib::Inflection.constantize(model_name.to_s)
122
+ model = ActiveSupport::Inflector.constantize(model_name.to_s)
123
123
  model.should respond_to(:default_repository_name)
124
124
  model.default_repository_name.should == :default
125
125
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 11
8
- - 0
9
- version: 0.11.0
8
+ - 1
9
+ version: 0.11.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Martin Gamsjaeger (snusnu), Yogo Team
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-09 00:00:00 -06:00
17
+ date: 2010-06-24 00:00:00 -06:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -32,9 +32,21 @@ dependencies:
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
35
- name: rspec
35
+ name: activesupport
36
36
  prerelease: false
37
37
  requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
38
50
  requirements:
39
51
  - - ~>
40
52
  - !ruby/object:Gem::Version
@@ -43,11 +55,11 @@ dependencies:
43
55
  - 3
44
56
  version: "1.3"
45
57
  type: :development
46
- version_requirements: *id002
58
+ version_requirements: *id003
47
59
  - !ruby/object:Gem::Dependency
48
60
  name: yard
49
61
  prerelease: false
50
- requirement: &id003 !ruby/object:Gem::Requirement
62
+ requirement: &id004 !ruby/object:Gem::Requirement
51
63
  requirements:
52
64
  - - ~>
53
65
  - !ruby/object:Gem::Version
@@ -56,7 +68,7 @@ dependencies:
56
68
  - 5
57
69
  version: "0.5"
58
70
  type: :development
59
- version_requirements: *id003
71
+ version_requirements: *id004
60
72
  description: Generates datamapper models from existing database schemas and export them to files
61
73
  email: irjudson [a] gmail [d] com
62
74
  executables: []