dm-reflection 0.0.5 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -1
- data/Rakefile +14 -21
- data/VERSION +1 -1
- data/dm-reflection.gemspec +4 -5
- data/lib/dm-reflection/adapters/mysql.rb +17 -2
- data/lib/dm-reflection/adapters/persevere.rb +1 -1
- data/lib/dm-reflection/adapters/postgres.rb +16 -1
- data/lib/dm-reflection/adapters/sqlite3.rb +18 -3
- data/lib/dm-reflection/reflection.rb +18 -8
- data/spec/reflection_spec.rb +44 -5
- data/spec/spec_helper.rb +3 -3
- metadata +6 -7
- data/lib/dm-reflection/version.rb +0 -5
data/.gitignore
CHANGED
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.
|
14
|
-
|
15
|
-
gem.
|
16
|
-
gem.
|
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.
|
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.
|
1
|
+
0.10.2
|
data/dm-reflection.gemspec
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dm-reflection}
|
8
|
-
s.version = "0.
|
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-
|
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
|
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/
|
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 =>
|
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|
|
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 =>
|
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 &&
|
63
|
-
|
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 =>
|
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
|
-
|
43
|
+
models[model_name] = namespace.const_set(model_name, anonymous_model)
|
44
|
+
end
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
-
|
61
|
+
|
62
|
+
models.to_a
|
53
63
|
end
|
54
64
|
end # module Reflection
|
55
65
|
|
data/spec/reflection_spec.rb
CHANGED
@@ -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, :
|
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, :
|
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
|
-
|
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
|
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
|
-
|
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"]
|
13
|
-
ENV["MYSQL_SPEC_URI"]
|
14
|
-
ENV["POSTGRES_SPEC_URI"]
|
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
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
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-
|
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
|
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/
|
97
|
+
homepage: http://github.com/yogo/dm-reflection
|
99
98
|
licenses: []
|
100
99
|
|
101
100
|
post_install_message:
|