dm-is-reflective 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.md +6 -0
- data/README.md +19 -11
- data/Rakefile +20 -2
- data/TODO.md +3 -8
- data/dm-is-reflective.gemspec +3 -3
- data/lib/dm-is-reflective/is/adapters/data_objects_adapter.rb +8 -25
- data/lib/dm-is-reflective/is/adapters/mysql_adapter.rb +13 -13
- data/lib/dm-is-reflective/is/adapters/postgres_adapter.rb +8 -10
- data/lib/dm-is-reflective/is/adapters/sqlite_adapter.rb +8 -7
- data/lib/dm-is-reflective/is/reflective.rb +5 -2
- data/lib/dm-is-reflective/version.rb +1 -1
- data/test/abstract.rb +16 -20
- data/test/test_dm-is-reflective.rb +6 -11
- metadata +3 -4
data/CHANGES.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## dm-is-reflective 1.1.0, 2013-01-11
|
4
|
+
|
5
|
+
* The need for dm-migrations is now removed.
|
6
|
+
* Added a few more datatypes. Thanks @onewheelskyward
|
7
|
+
* Tested against dm-core 1.2.0.
|
8
|
+
|
3
9
|
## dm-is-reflective 1.0.1, 2012-05-16
|
4
10
|
|
5
11
|
* allow_nil is more close to db's semantics, not required. Thanks miaout17.
|
data/README.md
CHANGED
@@ -13,6 +13,23 @@ by Lin Jen-Shin ([godfat](http://godfat.org))
|
|
13
13
|
DataMapper plugin that helps you manipulate an existing database.
|
14
14
|
It creates mappings between existing columns and model's properties.
|
15
15
|
|
16
|
+
## REQUIREMENTS:
|
17
|
+
|
18
|
+
* dm-core
|
19
|
+
* choose one: dm-sqlite-adapter, dm-postgres-adapter, dm-mysql-adapter
|
20
|
+
|
21
|
+
## INSTALLATION:
|
22
|
+
|
23
|
+
``` shell
|
24
|
+
gem install dm-is-reflective
|
25
|
+
```
|
26
|
+
|
27
|
+
``` ruby
|
28
|
+
gem 'dm-is-reflective',
|
29
|
+
:git => 'git://github.com/godfat/dm-is-reflective.git',
|
30
|
+
:submodules => true
|
31
|
+
```
|
32
|
+
|
16
33
|
## SYNOPSIS:
|
17
34
|
|
18
35
|
``` ruby
|
@@ -99,25 +116,16 @@ It creates mappings between existing columns and model's properties.
|
|
99
116
|
# => [DataMapper::Is::Reflective::User]
|
100
117
|
```
|
101
118
|
|
102
|
-
## REQUIREMENTS:
|
103
|
-
|
104
|
-
* dm-core
|
105
|
-
* dm-do-adapter
|
106
|
-
* choose one: dm-sqlite-adapter, dm-postgres-adapter, dm-mysql-adapter
|
107
|
-
|
108
|
-
## INSTALL:
|
109
|
-
|
110
|
-
gem install dm-is-reflective
|
111
|
-
|
112
119
|
## CONTRIBUTORS:
|
113
120
|
|
121
|
+
* Andrew Kreps (@onewheelskyward)
|
114
122
|
* Lin Jen-Shin (@godfat)
|
115
123
|
|
116
124
|
## LICENSE:
|
117
125
|
|
118
126
|
Apache License 2.0
|
119
127
|
|
120
|
-
Copyright (c) 2008-
|
128
|
+
Copyright (c) 2008-2013, Lin Jen-Shin (godfat)
|
121
129
|
|
122
130
|
Licensed under the Apache License, Version 2.0 (the "License");
|
123
131
|
you may not use this file except in compliance with the License.
|
data/Rakefile
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
begin
|
4
|
+
require "#{dir = File.dirname(__FILE__)}/task/gemgem"
|
5
|
+
rescue LoadError
|
6
|
+
sh "git submodule update --init"
|
7
|
+
exec Gem.ruby, "-S", "rake", *ARGV
|
8
|
+
end
|
5
9
|
|
10
|
+
Gemgem.dir = dir
|
6
11
|
($LOAD_PATH << File.expand_path("#{Gemgem.dir}/lib" )).uniq!
|
7
12
|
|
8
13
|
desc 'Generate gemspec'
|
@@ -21,3 +26,16 @@ task 'gem:spec' do
|
|
21
26
|
|
22
27
|
Gemgem.write
|
23
28
|
end
|
29
|
+
|
30
|
+
desc 'auto_migrate database'
|
31
|
+
task 'auto_migrate' do
|
32
|
+
require 'dm-migrations'
|
33
|
+
require './test/abstract'
|
34
|
+
require './test/test_dm-is-reflective'
|
35
|
+
include Abstract
|
36
|
+
[:SqliteTest, :PostgresTest, :MysqlTest].each do |db|
|
37
|
+
next unless Object.const_defined?(db)
|
38
|
+
Object.const_get(db).setup_data_mapper
|
39
|
+
[User, Comment, SuperUser].each(&:auto_migrate!)
|
40
|
+
end
|
41
|
+
end
|
data/TODO.md
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
# TODO
|
2
2
|
|
3
|
-
*
|
4
|
-
|
5
|
-
* extract some types to data_objects_adapter
|
3
|
+
* make sure reflective_lookup_primitive has everything as
|
4
|
+
type_map from dm-migrations
|
6
5
|
|
7
|
-
*
|
8
|
-
|
9
|
-
* better doc...
|
10
|
-
* 0.7.1 for more data types for postgresql adapter
|
11
|
-
* 0.9 automatic determine model relationship
|
6
|
+
* fix `rake auto_migrate`
|
12
7
|
|
13
8
|
* use bacon instead of minitest
|
data/dm-is-reflective.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "dm-is-reflective"
|
5
|
-
s.version = "1.0
|
5
|
+
s.version = "1.1.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Lin Jen-Shin (godfat)"]
|
9
|
-
s.date = "
|
9
|
+
s.date = "2013-01-11"
|
10
10
|
s.description = "DataMapper plugin that helps you manipulate an existing database.\nIt creates mappings between existing columns and model's properties."
|
11
11
|
s.email = ["godfat (XD) godfat.org"]
|
12
12
|
s.files = [
|
@@ -33,7 +33,7 @@ Gem::Specification.new do |s|
|
|
33
33
|
"test/test_dm-is-reflective.rb"]
|
34
34
|
s.homepage = "https://github.com/godfat/dm-is-reflective"
|
35
35
|
s.require_paths = ["lib"]
|
36
|
-
s.rubygems_version = "1.8.
|
36
|
+
s.rubygems_version = "1.8.23"
|
37
37
|
s.summary = "DataMapper plugin that helps you manipulate an existing database."
|
38
38
|
s.test_files = ["test/test_dm-is-reflective.rb"]
|
39
39
|
|
@@ -23,33 +23,14 @@ module DataMapper
|
|
23
23
|
# [:salt_second, String, {:required => false, :size => 50}]]
|
24
24
|
def fields storage
|
25
25
|
reflective_query_storage(storage).map{ |field|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# search from the most derived class
|
30
|
-
if k1 < k2 || k2 == Class then -1
|
31
|
-
elsif k1 > k2 || k1 == Class then 1
|
32
|
-
else 0
|
33
|
-
end
|
34
|
-
}.find{ |(klass, attrs)|
|
35
|
-
next false if [Object, Class, Time].include?(klass)
|
36
|
-
attrs[:primitive] == primitive
|
37
|
-
}
|
38
|
-
type = type ? type.first : reflective_lookup_primitive(primitive)
|
39
|
-
|
40
|
-
attrs = reflective_attributes(field)
|
41
|
-
|
42
|
-
type = if attrs[:serial] && type == Integer
|
26
|
+
attr = reflective_attributes(field)
|
27
|
+
type = reflective_lookup_primitive(reflective_primitive(field))
|
28
|
+
pick = if attr[:serial] && type == Integer
|
43
29
|
Property::Serial
|
44
|
-
|
45
|
-
elsif type == TrueClass
|
46
|
-
Property::Boolean
|
47
|
-
|
48
30
|
else
|
49
|
-
|
31
|
+
type
|
50
32
|
end
|
51
|
-
|
52
|
-
[reflective_field_name(field).to_sym, type, attrs]
|
33
|
+
[reflective_field_name(field).to_sym, pick, attr]
|
53
34
|
}
|
54
35
|
end
|
55
36
|
|
@@ -133,8 +114,10 @@ module DataMapper
|
|
133
114
|
model.__send__(:include, Resource)
|
134
115
|
model.is(:reflective)
|
135
116
|
model.storage_names[:default] = storage
|
136
|
-
model.__send__(:reflect, /.*/)
|
137
117
|
scope.const_set(Inflector.classify(storage), model)
|
118
|
+
model.__send__(:reflect, /.*/)
|
119
|
+
model.finalize if model.respond_to?(:finalize)
|
120
|
+
model
|
138
121
|
end
|
139
122
|
|
140
123
|
def reflective_lookup_primitive primitive
|
@@ -45,19 +45,19 @@ module DataMapper
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def reflective_lookup_primitive primitive
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
super(primitive)
|
48
|
+
case primitive.upcase
|
49
|
+
when 'YEAR' ; Integer
|
50
|
+
when /\w*INT(EGER)?( SIGNED| UNSIGNED)?( ZEROFILL)?/
|
51
|
+
; Integer
|
52
|
+
when /(DOUBLE|FLOAT|DECIMAL)( SIGNED| UNSIGNED)?( ZEROFILL)?/
|
53
|
+
; BigDecimal
|
54
|
+
when /\w*BLOB|\w*BINARY|ENUM|SET|CHAR/; String
|
55
|
+
when 'TIME' ; Time
|
56
|
+
when 'DATE' ; Date
|
57
|
+
when 'DATETIME', 'TIMESTAMP' ; DateTime
|
58
|
+
when 'BOOL', 'BOOLEAN' ; Property::Boolean
|
59
|
+
when /\w*TEXT/ ; Property::Text
|
60
|
+
end || super(primitive)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -68,17 +68,15 @@ module DataMapper
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def reflective_lookup_primitive primitive
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
super(primitive)
|
71
|
+
case primitive.upcase
|
72
|
+
when /^INT\d+$/ ; Integer
|
73
|
+
when /^FLOAT\d+$/ ; Float
|
74
|
+
when 'VARCHAR', 'BPCHAR'; String
|
75
|
+
when 'TIMESTAMP', 'DATE'; DateTime
|
76
|
+
when 'TEXT' ; Property::Text
|
77
|
+
when 'BOOL' ; Property::Boolean
|
78
|
+
end || super(primitive)
|
80
79
|
end
|
81
|
-
|
82
80
|
end
|
83
81
|
end
|
84
82
|
end
|
@@ -47,13 +47,14 @@ module DataMapper
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def reflective_lookup_primitive primitive
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
case primitive.upcase
|
51
|
+
when 'INTEGER' ; Integer
|
52
|
+
when 'REAL', 'NUMERIC'; Float
|
53
|
+
when 'VARCHAR' ; String
|
54
|
+
when 'TIMESTAMP' ; DateTime
|
55
|
+
when 'BOOLEAN' ; Property::Boolean
|
56
|
+
when 'TEXT' ; Property::Text
|
57
|
+
end || super(primitive)
|
57
58
|
end
|
58
59
|
end
|
59
60
|
end
|
@@ -15,7 +15,7 @@ module Reflective
|
|
15
15
|
DataMapper.repository(repo).adapter.fields(storage_name(repo))
|
16
16
|
end
|
17
17
|
|
18
|
-
# it
|
18
|
+
# it automatically creates reflection from storage fields to properties.
|
19
19
|
# i.e. you don't have to specify any property if you are connecting
|
20
20
|
# to an existing database.
|
21
21
|
# you can pass it Regexp to map any field it matched, or just
|
@@ -49,7 +49,7 @@ module Reflective
|
|
49
49
|
def reflect *targets
|
50
50
|
targets << /.*/ if targets.empty?
|
51
51
|
|
52
|
-
fields.map{ |field|
|
52
|
+
result = fields.map{ |field|
|
53
53
|
name, type, attrs = field
|
54
54
|
|
55
55
|
reflected = targets.each{ |target|
|
@@ -70,6 +70,9 @@ module Reflective
|
|
70
70
|
|
71
71
|
property(reflected, type, attrs) if reflected.kind_of?(Symbol)
|
72
72
|
}.compact
|
73
|
+
|
74
|
+
finalize if respond_to?(:finalize)
|
75
|
+
result
|
73
76
|
end
|
74
77
|
end # of ClassMethod
|
75
78
|
|
data/test/abstract.rb
CHANGED
@@ -4,8 +4,9 @@ require 'dm-migrations'
|
|
4
4
|
require 'dm-is-reflective'
|
5
5
|
|
6
6
|
module Abstract
|
7
|
-
def
|
8
|
-
|
7
|
+
def self.next_id
|
8
|
+
@id ||= 0
|
9
|
+
@id += 1
|
9
10
|
end
|
10
11
|
|
11
12
|
AttrCommon = {:allow_nil => true}
|
@@ -74,8 +75,6 @@ module Abstract
|
|
74
75
|
is :reflective
|
75
76
|
end
|
76
77
|
|
77
|
-
class Model; end
|
78
|
-
|
79
78
|
Tables = ['abstract_comments', 'abstract_super_users', 'abstract_users']
|
80
79
|
|
81
80
|
def sort_fields fields
|
@@ -85,18 +84,20 @@ module Abstract
|
|
85
84
|
end
|
86
85
|
|
87
86
|
def create_fake_model
|
88
|
-
model =
|
89
|
-
model.
|
90
|
-
|
87
|
+
model = Class.new
|
88
|
+
model.module_eval do
|
89
|
+
include DataMapper::Resource
|
90
|
+
property :id, DataMapper::Property::Serial
|
91
|
+
is :reflective
|
92
|
+
end
|
93
|
+
Abstract.const_set("Model#{Abstract.next_id}", model)
|
94
|
+
[model, self.class.setup_data_mapper]
|
91
95
|
end
|
92
96
|
|
93
97
|
attr_reader :dm
|
94
98
|
def setup
|
95
|
-
@dm = setup_data_mapper
|
96
|
-
|
97
|
-
User.auto_migrate!
|
98
|
-
Comment.auto_migrate!
|
99
|
-
SuperUser.auto_migrate!
|
99
|
+
@dm = self.class.setup_data_mapper
|
100
|
+
[User, Comment, SuperUser].each(&:auto_migrate!)
|
100
101
|
end
|
101
102
|
|
102
103
|
def new_scope
|
@@ -110,14 +111,12 @@ module Abstract
|
|
110
111
|
|
111
112
|
def test_create_comment
|
112
113
|
Comment.create(:title => 'XD')
|
113
|
-
assert_equal 1, Comment.first.id
|
114
114
|
assert_equal 'XD', Comment.first.title
|
115
115
|
end
|
116
116
|
|
117
117
|
def test_create_user
|
118
118
|
now = Time.now
|
119
119
|
User.create(:created_at => now)
|
120
|
-
assert_equal 1, User.first.id
|
121
120
|
assert_equal now.asctime, User.first.created_at.asctime
|
122
121
|
|
123
122
|
return now
|
@@ -136,7 +135,6 @@ module Abstract
|
|
136
135
|
assert_equal comment_fields, sort_fields(model.fields)
|
137
136
|
|
138
137
|
assert_equal 'XD', model.first.title
|
139
|
-
assert_equal 1, model.first.id
|
140
138
|
end
|
141
139
|
|
142
140
|
def test_reflect_and_create
|
@@ -146,10 +144,9 @@ module Abstract
|
|
146
144
|
|
147
145
|
model.create(:title => 'orz')
|
148
146
|
assert_equal 'orz', model.first.title
|
149
|
-
assert_equal 1, model.first.id
|
150
147
|
|
151
148
|
model.create
|
152
|
-
assert_equal 'default title', model.
|
149
|
+
assert_equal 'default title', model.last.title
|
153
150
|
end
|
154
151
|
|
155
152
|
def test_storages_and_fields
|
@@ -216,7 +213,7 @@ module Abstract
|
|
216
213
|
|
217
214
|
assert_equal 'XD', comment.first.title
|
218
215
|
comment.create(:title => 'orz', :body => 'dm-reflect')
|
219
|
-
assert_equal 'dm-reflect', comment.
|
216
|
+
assert_equal 'dm-reflect', comment.last.body
|
220
217
|
end
|
221
218
|
|
222
219
|
def test_auto_genclass
|
@@ -232,7 +229,7 @@ module Abstract
|
|
232
229
|
|
233
230
|
assert_equal now.asctime, user.first.created_at.asctime
|
234
231
|
user.create(:login => 'godfat')
|
235
|
-
assert_equal 'godfat', user.
|
232
|
+
assert_equal 'godfat', user.last.login
|
236
233
|
end
|
237
234
|
|
238
235
|
def test_auto_genclass_with_regexp
|
@@ -252,5 +249,4 @@ module Abstract
|
|
252
249
|
|
253
250
|
assert_equal model.properties.map(&:object_id).sort, mapped.map(&:object_id).sort
|
254
251
|
end
|
255
|
-
|
256
252
|
end
|
@@ -1,9 +1,5 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
require_relative 'abstract'
|
4
|
-
else
|
5
|
-
require File.dirname(__FILE__) + '/abstract'
|
6
|
-
end
|
2
|
+
require './test/abstract'
|
7
3
|
|
8
4
|
TestCase = begin
|
9
5
|
require 'minitest/unit'
|
@@ -14,7 +10,7 @@ TestCase = begin
|
|
14
10
|
Test::Unit::TestCase
|
15
11
|
end
|
16
12
|
|
17
|
-
%w[sqlite mysql
|
13
|
+
%w[sqlite postgres mysql].each{ |adapter|
|
18
14
|
begin
|
19
15
|
require "dm-#{adapter}-adapter"
|
20
16
|
rescue LoadError
|
@@ -26,15 +22,14 @@ TestCase = begin
|
|
26
22
|
class SqliteTest < TestCase
|
27
23
|
include Abstract
|
28
24
|
|
29
|
-
def setup_data_mapper
|
25
|
+
def self.setup_data_mapper
|
30
26
|
DataMapper.setup(:default, 'sqlite::memory:')
|
31
|
-
|
32
27
|
end
|
33
28
|
end if defined?(DataMapper::Adapters::SqliteAdapter)
|
34
29
|
|
35
30
|
class SqliteHashSetupTest < TestCase
|
36
31
|
include Abstract
|
37
|
-
def setup_data_mapper
|
32
|
+
def self.setup_data_mapper
|
38
33
|
DataMapper.setup(:default, :adapter => 'sqlite', :database => ':memory:')
|
39
34
|
end
|
40
35
|
end if defined?(DataMapper::Adapters::SqliteAdapter)
|
@@ -43,7 +38,7 @@ end if defined?(DataMapper::Adapters::SqliteAdapter)
|
|
43
38
|
class PostgresTest < TestCase
|
44
39
|
include Abstract
|
45
40
|
|
46
|
-
def setup_data_mapper
|
41
|
+
def self.setup_data_mapper
|
47
42
|
DataMapper.setup(:default, 'postgres://dm_is_reflective:godfat@localhost/dm_is_reflective')
|
48
43
|
end
|
49
44
|
end if defined?(DataMapper::Adapters::PostgresAdapter)
|
@@ -52,7 +47,7 @@ end if defined?(DataMapper::Adapters::PostgresAdapter)
|
|
52
47
|
class MysqlTest < TestCase
|
53
48
|
include Abstract
|
54
49
|
|
55
|
-
def setup_data_mapper
|
50
|
+
def self.setup_data_mapper
|
56
51
|
DataMapper.setup(:default, 'mysql://dm_is_reflective:godfat@localhost/dm_is_reflective')
|
57
52
|
end
|
58
53
|
end if defined?(DataMapper::Adapters::MysqlAdapter)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-is-reflective
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dm-core
|
@@ -157,10 +157,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
157
|
version: '0'
|
158
158
|
requirements: []
|
159
159
|
rubyforge_project:
|
160
|
-
rubygems_version: 1.8.
|
160
|
+
rubygems_version: 1.8.23
|
161
161
|
signing_key:
|
162
162
|
specification_version: 3
|
163
163
|
summary: DataMapper plugin that helps you manipulate an existing database.
|
164
164
|
test_files:
|
165
165
|
- test/test_dm-is-reflective.rb
|
166
|
-
has_rdoc:
|