dm-is-reflective 1.0.1 → 1.1.0
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/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:
|