dm-reflection 0.0.5 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -17,9 +17,10 @@ tmtags
17
17
  coverage
18
18
  rdoc
19
19
  pkg
20
+ *.gemspec
20
21
 
21
22
  ## PROJECT::SPECIFIC
22
23
 
23
24
  ## Yard
24
25
  .yardoc
25
- measurements/report.txt
26
+ measurements/report.txt
data/Rakefile CHANGED
@@ -1,38 +1,31 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require 'pathname'
3
4
 
4
5
  begin
5
-
6
- gem 'jeweler', '>= 1.4'
7
6
  require 'jeweler'
8
-
9
- require File.expand_path('../lib/dm-reflection/version', __FILE__)
10
-
11
7
  Jeweler::Tasks.new do |gem|
12
-
13
- gem.version = DataMapper::Reflection::VERSION
14
-
15
- gem.name = "dm-reflection"
16
- gem.summary = %Q{Generates datamapper models from existing database schemas}
17
- gem.description = %Q{Generates datamapper models from existing database schemas and export them to files}
18
- gem.email = "irjudson@gmail.com"
19
- gem.homepage = "http://github.com/irjudson/dm-reflection"
8
+ gem.name = %q{dm-reflection}
9
+ gem.summary = %q{Generates datamapper models from existing database schemas}
10
+ gem.description = %q{Generates datamapper models from existing database schemas and export them to files}
11
+ gem.email = "irjudson [a] gmail [d] com"
12
+ gem.homepage = "http://github.com/yogo/dm-reflection"
20
13
  gem.authors = ["Martin Gamsjaeger (snusnu), Yogo Team"]
21
-
22
- gem.add_dependency 'dm-core', '~> 0.10.2'
23
-
24
- gem.add_development_dependency 'rspec', '~> 1.3'
25
- gem.add_development_dependency 'yard', '~> 0.5'
26
-
14
+ gem.add_dependency('dm-core', '~> 0.10.2')
15
+ gem.add_development_dependency('rspec', ['~> 1.3'])
16
+ gem.add_development_dependency('yard', ['~> 0.5'])
27
17
  end
28
18
 
29
19
  Jeweler::GemcutterTasks.new
30
-
31
20
  FileList['tasks/**/*.rake'].each { |task| import task }
32
-
33
21
  rescue LoadError
34
22
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
35
23
  end
36
24
 
37
25
  task :spec => :check_dependencies
38
26
  task :default => :spec
27
+
28
+ ROOT = Pathname(__FILE__).dirname.expand_path
29
+ JRUBY = RUBY_PLATFORM =~ /java/
30
+ WINDOWS = Gem.win_platform?
31
+ SUDO = (WINDOWS || JRUBY) ? '' : ('sudo' unless ENV['SUDOLESS'])
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.10.2
@@ -5,13 +5,13 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dm-reflection}
8
- s.version = "0.0.5"
8
+ s.version = "0.10.2"
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-05-03}
12
+ s.date = %q{2010-05-05}
13
13
  s.description = %q{Generates datamapper models from existing database schemas and export them to files}
14
- s.email = %q{irjudson@gmail.com}
14
+ s.email = %q{irjudson [a] gmail [d] com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
17
  "README.rdoc"
@@ -31,7 +31,6 @@ Gem::Specification.new do |s|
31
31
  "lib/dm-reflection/adapters/sqlite3.rb",
32
32
  "lib/dm-reflection/builders/source_builder.rb",
33
33
  "lib/dm-reflection/reflection.rb",
34
- "lib/dm-reflection/version.rb",
35
34
  "spec/persevere_reflection_spec.rb",
36
35
  "spec/rcov.opts",
37
36
  "spec/reflection_spec.rb",
@@ -45,7 +44,7 @@ Gem::Specification.new do |s|
45
44
  "tasks/yard.rake",
46
45
  "tasks/yardstick.rake"
47
46
  ]
48
- s.homepage = %q{http://github.com/irjudson/dm-reflection}
47
+ s.homepage = %q{http://github.com/yogo/dm-reflection}
49
48
  s.rdoc_options = ["--charset=UTF-8"]
50
49
  s.require_paths = ["lib"]
51
50
  s.rubygems_version = %q{1.3.6}
@@ -74,14 +74,29 @@ module DataMapper
74
74
  type = DataMapper::Types::Serial
75
75
  end
76
76
 
77
+ field_name = column.field.downcase
78
+
77
79
  attribute = {
78
- :name => column.field.downcase,
80
+ :name => field_name,
79
81
  :type => type,
80
82
  :required => column.null == 'NO',
81
83
  :default => column.default,
82
84
  :key => column.key == 'PRI',
83
85
  }
84
-
86
+
87
+ if type == Integer && field_name[-3,3] == "_id"
88
+ # This is a foriegn key. So this model belongs_to the other (_id) one.
89
+ # Add a special set of values and flag this as a relationship so the reflection code
90
+ # can rebuild the relationship when it's building the model.
91
+ attribute[:type] = DataMapper::Associations::Relationship
92
+ attribute[:relationship] = {
93
+ :parent => Extlib::Inflection.classify(field_name[0..-4]),
94
+ :child => Extlib::Inflection.classify(table),
95
+ # When we can detect more from the database we can optimize this
96
+ :cardinality => Infinity,
97
+ :bidirectional => true }
98
+ end
99
+
85
100
  # TODO: use the naming convention to compare the name vs the column name
86
101
  unless attribute[:name] == column.field
87
102
  attribute[:field] = column.field
@@ -90,7 +90,7 @@ module DataMapper
90
90
 
91
91
  # Turns 'class_path/class' into 'ClassPath::Class
92
92
  def derive_relationship_model(input)
93
- input.match(/(Class)?\/([a-z\-\/\_]+)$/)[-1].split('/').map{|i| ExtLib::Inflection.classify(i) }.join("::")
93
+ input.match(/(Class)?\/([a-z\-\/\_]+)$/)[-1].split('/').map{|i| Extlib::Inflection.classify(i) }.join("::")
94
94
  end
95
95
 
96
96
  end # module PersevereAdapter
@@ -102,9 +102,11 @@ module DataMapper
102
102
  if length
103
103
  length = (required ? 1 : 0)..length
104
104
  end
105
+
106
+ field_name = column.column_name.downcase
105
107
 
106
108
  attribute = {
107
- :name => column.column_name.downcase,
109
+ :name => field_name,
108
110
  :type => type,
109
111
  :required => required,
110
112
  :default => default,
@@ -112,6 +114,19 @@ module DataMapper
112
114
  :length => length,
113
115
  }
114
116
 
117
+ if type == Integer && field_name[-3,3] == "_id"
118
+ # This is a foriegn key. So this model belongs_to the other (_id) one.
119
+ # Add a special set of values and flag this as a relationship so the reflection code
120
+ # can rebuild the relationship when it's building the model.
121
+ attribute[:type] = DataMapper::Associations::Relationship
122
+ attribute[:relationship] = {
123
+ :parent => Extlib::Inflection.classify(field_name[0..-4]),
124
+ :child => Extlib::Inflection.classify(table),
125
+ # When we can detect more from the database we can optimize this
126
+ :cardinality => Infinity,
127
+ :bidirectional => true }
128
+ end
129
+
115
130
  # TODO: use the naming convention to compare the name vs the column name
116
131
  unless attribute[:name] == column.column_name
117
132
  attribute[:field] = column.column_name
@@ -59,18 +59,33 @@ module DataMapper
59
59
  type = get_type(column.type)
60
60
  default = column.dflt_value
61
61
 
62
- if type == Integer && default
63
- default = default.to_i
62
+ if type == Integer && column.pk == 1
63
+ type = DataMapper::Types::Serial
64
64
  end
65
65
 
66
+ field_name = column.name.downcase
67
+
66
68
  attribute = {
67
- :name => column.name.downcase,
69
+ :name => field_name,
68
70
  :type => type,
69
71
  :required => column.notnull == 1,
70
72
  :default => default,
71
73
  :key => column.pk == 1,
72
74
  }
73
75
 
76
+ if type == Integer && field_name[-3,3] == "_id"
77
+ # This is a foriegn key. So this model belongs_to the other (_id) one.
78
+ # Add a special set of values and flag this as a relationship so the reflection code
79
+ # can rebuild the relationship when it's building the model.
80
+ attribute[:type] = DataMapper::Associations::Relationship
81
+ attribute[:relationship] = {
82
+ :parent => Extlib::Inflection.classify(field_name[0..-4]),
83
+ :child => Extlib::Inflection.classify(table),
84
+ # When we can detect more from the database we can optimize this
85
+ :cardinality => Infinity,
86
+ :bidirectional => true }
87
+ end
88
+
74
89
  # TODO: use the naming convention to compare the name vs the column name
75
90
  unless attribute[:name] == column.name
76
91
  attribute[:field] = column.name
@@ -10,7 +10,7 @@ module DataMapper
10
10
  def self.reflect(repository, namespace = Object, overwrite = false)
11
11
  adapter = DataMapper.repository(repository).adapter
12
12
 
13
- models = []
13
+ models = Hash.new
14
14
 
15
15
  adapter.get_storage_names.each do |storage_name|
16
16
  namespace_parts = storage_name.split('__').map do |part|
@@ -40,16 +40,26 @@ module DataMapper
40
40
  end
41
41
  end
42
42
 
43
- model = namespace.const_set(model_name, anonymous_model)
43
+ models[model_name] = namespace.const_set(model_name, anonymous_model)
44
+ end
44
45
 
45
- adapter.get_properties(storage_name).each do |attribute|
46
- attribute.delete_if { |k,v| v.nil? }
47
- model.property(attribute.delete(:name).to_sym, attribute.delete(:type), attribute)
46
+ models.values.each do |model|
47
+ adapter.get_properties(model.storage_name).each do |attribute|
48
+ if attribute[:type] == DataMapper::Associations::Relationship
49
+ parent = models[attribute[:relationship][:parent]]
50
+ child = models[attribute[:relationship][:child]]
51
+ child.belongs_to(parent.name.downcase.to_sym)
52
+ if attribute[:relationship][:bidirectional]
53
+ parent.has(attribute[:relationship][:cardinality], child.name.pluralize.downcase.to_sym)
54
+ end
55
+ else
56
+ attribute.delete_if { |k,v| v.nil? }
57
+ model.property(attribute.delete(:name).to_sym, attribute.delete(:type), attribute)
58
+ end
48
59
  end
49
-
50
- models << model
51
60
  end
52
- models
61
+
62
+ models.to_a
53
63
  end
54
64
  end # module Reflection
55
65
 
@@ -1,6 +1,9 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
  require 'dm-reflection/builders/source_builder'
3
3
 
4
+ # Property options are in the order specified below
5
+ # because they pass tests (ruby hash keys are not ordered)
6
+
4
7
  BLOGPOST = <<-RUBY
5
8
  class BlogPost
6
9
 
@@ -9,7 +12,7 @@ class BlogPost
9
12
  property :id, Serial
10
13
 
11
14
  property :created_at, DateTime
12
- property :body, Text, :length => 65535, :lazy => true
15
+ property :body, Text, :lazy => true, :length => 65535
13
16
  property :updated_at, DateTime
14
17
 
15
18
 
@@ -24,7 +27,7 @@ class Comment
24
27
  property :id, Serial
25
28
 
26
29
  property :created_at, DateTime
27
- property :body, Text, :length => 65535, :lazy => true
30
+ property :body, Text, :lazy => true, :length => 65535
28
31
  property :updated_at, DateTime
29
32
  property :score, Integer
30
33
 
@@ -32,7 +35,41 @@ class Comment
32
35
  end
33
36
  RUBY
34
37
 
35
- REFLECTION_SOURCES = [ BLOGPOST, COMMENT ]
38
+ PARENT = <<-RUBY
39
+ class Parent
40
+
41
+ include DataMapper::Resource
42
+
43
+ property :id, Serial
44
+
45
+ property :created_at, DateTime
46
+ property :words, Text, :lazy => true, :length => 65535
47
+ property :updated_at, DateTime
48
+ property :name, Text, :lazy => true, :length => 65535
49
+
50
+ has n, :children
51
+
52
+ end
53
+ RUBY
54
+
55
+ CHILD = <<-RUBY
56
+ class Child
57
+
58
+ include DataMapper::Resource
59
+
60
+ property :id, Serial
61
+
62
+ property :created_at, DateTime
63
+ property :description, Text, :lazy => true, :length => 65535
64
+ property :updated_at, DateTime
65
+ property :name, Integer
66
+
67
+ belongs_to :parent
68
+
69
+ end
70
+ RUBY
71
+
72
+ REFLECTION_SOURCES = [ BLOGPOST, COMMENT, PARENT, CHILD ]
36
73
 
37
74
  describe 'The DataMapper reflection module' do
38
75
 
@@ -42,8 +79,10 @@ describe 'The DataMapper reflection module' do
42
79
  REFLECTION_SOURCES.each { |source| eval(source) }
43
80
 
44
81
  @models = {
45
- :BlogPost => BLOGPOST,
82
+ :BlogPost => BLOGPOST,
46
83
  :Comment => COMMENT,
84
+ :Parent => PARENT,
85
+ :Child => CHILD
47
86
  }
48
87
 
49
88
  @models.each_key { |model| Extlib::Inflection.constantize(model.to_s).auto_migrate! }
@@ -69,7 +108,7 @@ describe 'The DataMapper reflection module' do
69
108
  @models.each_pair do |model_name, source|
70
109
  model = Extlib::Inflection.constantize(model_name.to_s)
71
110
  reflected_source = model.to_ruby
72
- model.to_ruby.should == source
111
+ reflected_source.should == source
73
112
  end
74
113
  end
75
114
  end
data/spec/spec_helper.rb CHANGED
@@ -9,9 +9,9 @@ require 'dm-reflection'
9
9
  require 'spec'
10
10
  require 'spec/autorun'
11
11
 
12
- ENV["SQLITE3_SPEC_URI"] ||= 'sqlite3::memory:'
13
- ENV["MYSQL_SPEC_URI"] ||= 'mysql://localhost/dm-reflections_test'
14
- ENV["POSTGRES_SPEC_URI"] ||= 'postgres://postgres@localhost/dm-reflection_test'
12
+ ENV["SQLITE3_SPEC_URI"] ||= 'sqlite3::memory:'
13
+ ENV["MYSQL_SPEC_URI"] ||= 'mysql://localhost/dm_reflection_test'
14
+ ENV["POSTGRES_SPEC_URI"] ||= 'postgres://postgres@localhost/dm-reflection_test'
15
15
  ENV["PERSEVERE_SPEC_URI"] ||= 'persevere://localhost:8080/'
16
16
 
17
17
  def setup_adapter(name, default_uri = nil)
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 0
8
- - 5
9
- version: 0.0.5
7
+ - 10
8
+ - 2
9
+ version: 0.10.2
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-05-03 00:00:00 -06:00
17
+ date: 2010-05-05 00:00:00 -06:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -58,7 +58,7 @@ dependencies:
58
58
  type: :development
59
59
  version_requirements: *id003
60
60
  description: Generates datamapper models from existing database schemas and export them to files
61
- email: irjudson@gmail.com
61
+ email: irjudson [a] gmail [d] com
62
62
  executables: []
63
63
 
64
64
  extensions: []
@@ -81,7 +81,6 @@ files:
81
81
  - lib/dm-reflection/adapters/sqlite3.rb
82
82
  - lib/dm-reflection/builders/source_builder.rb
83
83
  - lib/dm-reflection/reflection.rb
84
- - lib/dm-reflection/version.rb
85
84
  - spec/persevere_reflection_spec.rb
86
85
  - spec/rcov.opts
87
86
  - spec/reflection_spec.rb
@@ -95,7 +94,7 @@ files:
95
94
  - tasks/yard.rake
96
95
  - tasks/yardstick.rake
97
96
  has_rdoc: true
98
- homepage: http://github.com/irjudson/dm-reflection
97
+ homepage: http://github.com/yogo/dm-reflection
99
98
  licenses: []
100
99
 
101
100
  post_install_message:
@@ -1,5 +0,0 @@
1
- module DataMapper
2
- module Reflection
3
- VERSION = '0.0.5'.freeze
4
- end
5
- end