dm-is-reflective 1.1.0 → 1.2.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.
- checksums.yaml +7 -0
- data/.travis.yml +15 -0
- data/CHANGES.md +8 -0
- data/Gemfile +5 -1
- data/README.md +103 -86
- data/Rakefile +1 -14
- data/bin/dm-is-reflective +4 -0
- data/dm-is-reflective.gemspec +24 -12
- data/lib/dm-is-reflective.rb +4 -5
- data/lib/dm-is-reflective/adapters/data_objects_adapter.rb +136 -0
- data/lib/dm-is-reflective/adapters/mysql_adapter.rb +63 -0
- data/lib/dm-is-reflective/adapters/postgres_adapter.rb +80 -0
- data/lib/dm-is-reflective/adapters/sqlite_adapter.rb +57 -0
- data/lib/dm-is-reflective/{is/reflective.rb → reflective.rb} +18 -7
- data/lib/dm-is-reflective/runner.rb +87 -0
- data/lib/dm-is-reflective/test.rb +279 -0
- data/lib/dm-is-reflective/version.rb +2 -6
- data/task/gemgem.rb +7 -6
- data/test/test_mysql.rb +23 -0
- data/test/test_postgres.rb +23 -0
- data/test/test_sqlite.rb +10 -0
- data/test/test_to_source.rb +55 -0
- metadata +43 -46
- data/lib/dm-is-reflective/is/adapters/data_objects_adapter.rb +0 -138
- data/lib/dm-is-reflective/is/adapters/mysql_adapter.rb +0 -64
- data/lib/dm-is-reflective/is/adapters/postgres_adapter.rb +0 -82
- data/lib/dm-is-reflective/is/adapters/sqlite_adapter.rb +0 -61
- data/test/abstract.rb +0 -252
- data/test/test_dm-is-reflective.rb +0 -53
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a4a92f58af6a1c63b6bb445e06fdc573239ef558
|
4
|
+
data.tar.gz: 4577c3ed73a122c4ddd09e62c8c0e64802e49540
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f271c3864848cfb098e7f7b32887831700617668c001a56f25f0be1a0497d0e488db5f8970ad7e96ee9ab9aecb4fd333b4fa71c70de48afd435929c266751f5c
|
7
|
+
data.tar.gz: a139f550d6b69b36ddb824eec2ca59b4ec157d1289d39cdcc31f268a5d50a7abb90abcb1b48a05f7cdb0784edfb31b28440078adaef7f3b721ccb82d5f7e1944
|
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
before_install:
|
2
|
+
- 'git submodule update --init'
|
3
|
+
- mysql -e 'create database myapp_test;'
|
4
|
+
- psql -c 'create database myapp_test;' -U postgres
|
5
|
+
|
6
|
+
script: 'ruby -r bundler/setup -S rake test'
|
7
|
+
|
8
|
+
env:
|
9
|
+
- 'RBXOPT=-X19'
|
10
|
+
|
11
|
+
rvm:
|
12
|
+
- 1.9.3
|
13
|
+
- 2.0.0
|
14
|
+
- rbx-head
|
15
|
+
- jruby-head
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## dm-is-reflective 1.2.0, 2013-05-14
|
4
|
+
|
5
|
+
* We got a bunch of internal renaming.
|
6
|
+
* Added DataMapper::Resource#to_source.
|
7
|
+
* Added an executable which generates sources for you.
|
8
|
+
* Fixed MySQL issues with setting up with a hash rather than URI.
|
9
|
+
* Fixed SQLite issues without loading dm-migrations.
|
10
|
+
|
3
11
|
## dm-is-reflective 1.1.0, 2013-01-11
|
4
12
|
|
5
13
|
* The need for dm-migrations is now removed.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# dm-is-reflective
|
1
|
+
# dm-is-reflective [](http://travis-ci.org/godfat/dm-is-reflective)
|
2
2
|
|
3
3
|
by Lin Jen-Shin ([godfat](http://godfat.org))
|
4
4
|
|
@@ -21,99 +21,116 @@ It creates mappings between existing columns and model's properties.
|
|
21
21
|
## INSTALLATION:
|
22
22
|
|
23
23
|
``` shell
|
24
|
-
|
24
|
+
gem install dm-is-reflective
|
25
25
|
```
|
26
26
|
|
27
27
|
``` ruby
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
gem 'dm-is-reflective',
|
29
|
+
:git => 'git://github.com/godfat/dm-is-reflective.git',
|
30
|
+
:submodules => true
|
31
31
|
```
|
32
32
|
|
33
33
|
## SYNOPSIS:
|
34
34
|
|
35
|
+
### Generating sources from a DATABASE_URI
|
36
|
+
|
37
|
+
We also have an executable to generate sources for you.
|
38
|
+
|
39
|
+
```
|
40
|
+
Usage: dm-is-reflective DATABASE_URI
|
41
|
+
-s, --scope SCOPE SCOPE where the models should go (default: Object)
|
42
|
+
-o, --output DIRECTORY DIRECTORY where the output goes (default: dm-is-reflective)
|
43
|
+
-h, --help Print this message
|
44
|
+
-v, --version Print the version
|
45
|
+
```
|
46
|
+
|
47
|
+
### API
|
48
|
+
|
35
49
|
``` ruby
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
50
|
+
require 'dm-is-reflective' # this would require 'dm-core'
|
51
|
+
dm = DataMapper.setup :default, 'sqlite::memory:'
|
52
|
+
|
53
|
+
class User
|
54
|
+
include DataMapper::Resource
|
55
|
+
is :reflective
|
56
|
+
|
57
|
+
# map all, returning an array of properties indicating fields it mapped
|
58
|
+
reflect /.*/ # e.g. => [#<Property:#<Class:0x18f89b8>:id>,
|
59
|
+
# #<Property:#<Class:0x18f89b8>:title>,
|
60
|
+
# #<Property:#<Class:0x18f89b8>:body>,
|
61
|
+
# #<Property:#<Class:0x18f89b8>:user_id>]
|
62
|
+
|
63
|
+
# map all (with no argument at all)
|
64
|
+
reflect
|
65
|
+
|
66
|
+
# mapping for field name ended with _at, and started with salt_
|
67
|
+
reflect /_at$/, /^salt_/
|
68
|
+
|
69
|
+
# mapping id and email
|
70
|
+
reflect :id, :email
|
71
|
+
|
72
|
+
# mapping all fields with type String, and id
|
73
|
+
reflect String, :id
|
74
|
+
|
75
|
+
# mapping login, and all fields with type Integer
|
76
|
+
reflect :login, Integer
|
77
|
+
end
|
78
|
+
|
79
|
+
# there's no guarantee of the order in storages array
|
80
|
+
dm.storages
|
81
|
+
# => ['users']
|
82
|
+
|
83
|
+
# there's no guarantee of the order in fields array
|
84
|
+
User.fields
|
85
|
+
# => [[:created_at, DateTime, {:required => false}],
|
86
|
+
[:email, String, {:required => false, :length => 255,
|
87
|
+
:default => 'nospam@nospam.tw'}],
|
88
|
+
[:id, Serial, {:required => true, :serial => true,
|
89
|
+
:key => true}],
|
90
|
+
[:salt_first, String, {:required => false, :length => 50}],
|
91
|
+
[:salt_second, String, {:required => false, :length => 50}]]
|
92
|
+
|
93
|
+
dm.fields('users').sort_by{ |field| field.first.to_s } ==
|
94
|
+
User.fields.sort_by{ |field| field.first.to_s }
|
95
|
+
# => true
|
96
|
+
|
97
|
+
dm.storages_and_fields
|
98
|
+
# => {'users' => [[:id, Serial, {:required => true,
|
99
|
+
:serial => true,
|
100
|
+
:key => true}],
|
101
|
+
[:email, String, {:required => false,
|
102
|
+
:default =>
|
103
|
+
'nospam@nospam.tw'}],
|
104
|
+
[:created_at, DateTime, {:required => false}],
|
105
|
+
[:salt_first, String, {:required => false,
|
106
|
+
:length => 50}],
|
107
|
+
[:salt_second, String, {:required => false,
|
108
|
+
:length => 50}]]}
|
109
|
+
|
110
|
+
# there's no guarantee of the order in returned array
|
111
|
+
dm.auto_genclass!
|
112
|
+
# => [DataMapper::Is::Reflective::User,
|
113
|
+
DataMapper::Is::Reflective::SchemaInfo,
|
114
|
+
DataMapper::Is::Reflective::Session]
|
115
|
+
|
116
|
+
# you can change the scope of generated models:
|
117
|
+
dm.auto_genclass! :scope => Object
|
118
|
+
# => [User, SchemaInfo, Session]
|
119
|
+
|
120
|
+
# you can generate classes for tables you specified only:
|
121
|
+
dm.auto_genclass! :scope => Object, :storages => /^phpbb_/
|
122
|
+
# => [PhpbbUser, PhpbbPost, PhpbbConfig]
|
123
|
+
|
124
|
+
# you can generate classes with String too:
|
125
|
+
dm.auto_genclass! :storages => ['users', 'config'], :scope => Object
|
126
|
+
# => [User, Config]
|
127
|
+
|
128
|
+
# you can generate a class only:
|
129
|
+
dm.auto_genclass! :storages => 'users'
|
130
|
+
# => [DataMapper::Is::Reflective::User]
|
131
|
+
|
132
|
+
# you can also generate the source from models:
|
133
|
+
puts User.to_source
|
117
134
|
```
|
118
135
|
|
119
136
|
## CONTRIBUTORS:
|
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ task 'gem:spec' do
|
|
15
15
|
Gemgem.spec = Gemgem.create do |s|
|
16
16
|
require 'dm-is-reflective/version'
|
17
17
|
s.name = 'dm-is-reflective'
|
18
|
-
s.version =
|
18
|
+
s.version = DmIsReflective::VERSION
|
19
19
|
|
20
20
|
%w[dm-core dm-do-adapter].each{ |g| s.add_runtime_dependency(g) }
|
21
21
|
%w[dm-migrations
|
@@ -26,16 +26,3 @@ task 'gem:spec' do
|
|
26
26
|
|
27
27
|
Gemgem.write
|
28
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/dm-is-reflective.gemspec
CHANGED
@@ -2,43 +2,55 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "dm-is-reflective"
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.2.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 = "2013-
|
9
|
+
s.date = "2013-05-14"
|
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
|
+
s.executables = ["dm-is-reflective"]
|
12
13
|
s.files = [
|
13
14
|
".gitignore",
|
14
15
|
".gitmodules",
|
16
|
+
".travis.yml",
|
15
17
|
"CHANGES.md",
|
16
18
|
"Gemfile",
|
17
19
|
"LICENSE",
|
18
20
|
"README.md",
|
19
21
|
"Rakefile",
|
20
22
|
"TODO.md",
|
23
|
+
"bin/dm-is-reflective",
|
21
24
|
"dm-is-reflective.gemspec",
|
22
25
|
"lib/dm-is-reflective.rb",
|
23
|
-
"lib/dm-is-reflective/
|
24
|
-
"lib/dm-is-reflective/
|
25
|
-
"lib/dm-is-reflective/
|
26
|
-
"lib/dm-is-reflective/
|
27
|
-
"lib/dm-is-reflective/
|
26
|
+
"lib/dm-is-reflective/adapters/data_objects_adapter.rb",
|
27
|
+
"lib/dm-is-reflective/adapters/mysql_adapter.rb",
|
28
|
+
"lib/dm-is-reflective/adapters/postgres_adapter.rb",
|
29
|
+
"lib/dm-is-reflective/adapters/sqlite_adapter.rb",
|
30
|
+
"lib/dm-is-reflective/reflective.rb",
|
31
|
+
"lib/dm-is-reflective/runner.rb",
|
32
|
+
"lib/dm-is-reflective/test.rb",
|
28
33
|
"lib/dm-is-reflective/version.rb",
|
29
34
|
"task/.gitignore",
|
30
35
|
"task/gemgem.rb",
|
31
|
-
"test/abstract.rb",
|
32
36
|
"test/setup_db.sh",
|
33
|
-
"test/
|
37
|
+
"test/test_mysql.rb",
|
38
|
+
"test/test_postgres.rb",
|
39
|
+
"test/test_sqlite.rb",
|
40
|
+
"test/test_to_source.rb"]
|
34
41
|
s.homepage = "https://github.com/godfat/dm-is-reflective"
|
42
|
+
s.licenses = ["Apache License 2.0"]
|
35
43
|
s.require_paths = ["lib"]
|
36
|
-
s.rubygems_version = "
|
44
|
+
s.rubygems_version = "2.0.3"
|
37
45
|
s.summary = "DataMapper plugin that helps you manipulate an existing database."
|
38
|
-
s.test_files = [
|
46
|
+
s.test_files = [
|
47
|
+
"test/test_mysql.rb",
|
48
|
+
"test/test_postgres.rb",
|
49
|
+
"test/test_sqlite.rb",
|
50
|
+
"test/test_to_source.rb"]
|
39
51
|
|
40
52
|
if s.respond_to? :specification_version then
|
41
|
-
s.specification_version =
|
53
|
+
s.specification_version = 4
|
42
54
|
|
43
55
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
44
56
|
s.add_runtime_dependency(%q<dm-core>, [">= 0"])
|
data/lib/dm-is-reflective.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
|
2
|
-
gem 'dm-core', '>=1.0.0'
|
3
2
|
require 'dm-core'
|
4
3
|
require 'dm-do-adapter'
|
5
4
|
|
6
|
-
require 'dm-is-reflective/
|
7
|
-
require 'dm-is-reflective/
|
5
|
+
require 'dm-is-reflective/reflective'
|
6
|
+
require 'dm-is-reflective/adapters/data_objects_adapter'
|
8
7
|
|
9
|
-
DataMapper::Model.append_extensions(
|
8
|
+
DataMapper::Model.append_extensions(DmIsReflective)
|
10
9
|
|
11
10
|
DataMapper::Adapters::DataObjectsAdapter.__send__(:include,
|
12
|
-
|
11
|
+
DmIsReflective::DataObjectsAdapter)
|
@@ -0,0 +1,136 @@
|
|
1
|
+
|
2
|
+
module DmIsReflective::DataObjectsAdapter
|
3
|
+
include DataMapper
|
4
|
+
|
5
|
+
# returns all tables' name in the repository.
|
6
|
+
# e.g.
|
7
|
+
# ['comments', 'users']
|
8
|
+
def storages
|
9
|
+
reflective_auto_load_adapter_extension
|
10
|
+
storages # call the overrided method
|
11
|
+
end
|
12
|
+
|
13
|
+
# returns all fields, with format [[name, type, attrs]]
|
14
|
+
# e.g.
|
15
|
+
# [[:created_at, DateTime, {:required => false}],
|
16
|
+
# [:email, String, {:required => false, :size => 255,
|
17
|
+
# :default => 'nospam@nospam.tw'}],
|
18
|
+
# [:id, DataMapper::Property::Serial, {:required => true, :serial => true,
|
19
|
+
# :key => true}],
|
20
|
+
# [:salt_first, String, {:required => false, :size => 50}],
|
21
|
+
# [:salt_second, String, {:required => false, :size => 50}]]
|
22
|
+
def fields storage
|
23
|
+
reflective_query_storage(storage).map{ |field|
|
24
|
+
attr = reflective_attributes(field)
|
25
|
+
type = reflective_lookup_primitive(reflective_primitive(field))
|
26
|
+
pick = if attr[:serial] && type == Integer
|
27
|
+
Property::Serial
|
28
|
+
else
|
29
|
+
type
|
30
|
+
end
|
31
|
+
[reflective_field_name(field).to_sym, pick, attr]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
# returns a hash with storage names in keys and
|
36
|
+
# corresponded fields in values. e.g.
|
37
|
+
# {'users' => [[:id, Integer, {:required => true,
|
38
|
+
# :serial => true,
|
39
|
+
# :key => true}],
|
40
|
+
# [:email, String, {:required => false,
|
41
|
+
# :default => 'nospam@nospam.tw'}],
|
42
|
+
# [:created_at, DateTime, {:required => false}],
|
43
|
+
# [:salt_first, String, {:required => false, :size => 50}],
|
44
|
+
# [:salt_second, String, {:required => false, :size => 50}]]}
|
45
|
+
# see AbstractAdapter#storages and AbstractAdapter#fields for detail
|
46
|
+
def storages_and_fields
|
47
|
+
storages.inject({}){ |result, storage|
|
48
|
+
result[storage] = fields(storage)
|
49
|
+
result
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
# automaticly generate model class(es) and reflect
|
54
|
+
# all fields with reflect /.*/ for you.
|
55
|
+
# e.g.
|
56
|
+
# dm.auto_genclass!
|
57
|
+
# # => [DataMapper::Is::Reflective::User,
|
58
|
+
# # DataMapper::Is::Reflective::SchemaInfo,
|
59
|
+
# # DataMapper::Is::Reflective::Session]
|
60
|
+
#
|
61
|
+
# you can change the scope of generated models:
|
62
|
+
# e.g.
|
63
|
+
# dm.auto_genclass! :scope => Object
|
64
|
+
# # => [User, SchemaInfo, Session]
|
65
|
+
#
|
66
|
+
# you can generate classes for tables you specified only:
|
67
|
+
# e.g.
|
68
|
+
# dm.auto_genclass! :scope => Object, :storages => /^phpbb_/
|
69
|
+
# # => [PhpbbUser, PhpbbPost, PhpbbConfig]
|
70
|
+
#
|
71
|
+
# you can generate classes with String too:
|
72
|
+
# e.g.
|
73
|
+
# dm.auto_genclass! :storages => ['users', 'config'], :scope => Object
|
74
|
+
# # => [User, Config]
|
75
|
+
#
|
76
|
+
# you can generate a class only:
|
77
|
+
# e.g.
|
78
|
+
# dm.auto_genclass! :storages => 'users'
|
79
|
+
# # => [DataMapper::Is::Reflective::User]
|
80
|
+
def auto_genclass! opts = {}
|
81
|
+
opts[:scope] ||= DmIsReflective
|
82
|
+
opts[:storages] ||= /.*/
|
83
|
+
opts[:storages] = [opts[:storages]].flatten
|
84
|
+
|
85
|
+
storages.map{ |storage|
|
86
|
+
|
87
|
+
mapped = opts[:storages].each{ |target|
|
88
|
+
case target
|
89
|
+
when Regexp;
|
90
|
+
break storage if storage =~ target
|
91
|
+
|
92
|
+
when Symbol, String;
|
93
|
+
break storage if storage == target.to_s
|
94
|
+
|
95
|
+
else
|
96
|
+
raise ArgumentError.new("invalid argument: #{target.inspect}")
|
97
|
+
end
|
98
|
+
}
|
99
|
+
|
100
|
+
reflective_genclass(mapped, opts[:scope]) if mapped.kind_of?(String)
|
101
|
+
}.compact
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
def reflective_query_storage storage
|
106
|
+
reflective_auto_load_adapter_extension
|
107
|
+
reflective_query_storage(storage) # call the overrided method
|
108
|
+
end
|
109
|
+
|
110
|
+
def reflective_genclass storage, scope
|
111
|
+
model = Class.new
|
112
|
+
model.__send__(:include, Resource)
|
113
|
+
model.is(:reflective)
|
114
|
+
model.storage_names[:default] = storage
|
115
|
+
scope.const_set(Inflector.classify(storage), model)
|
116
|
+
model.__send__(:reflect, /.*/)
|
117
|
+
model.finalize if model.respond_to?(:finalize)
|
118
|
+
model
|
119
|
+
end
|
120
|
+
|
121
|
+
def reflective_lookup_primitive primitive
|
122
|
+
raise TypeError.new("#{primitive} not found for #{self.class}")
|
123
|
+
end
|
124
|
+
|
125
|
+
def reflective_auto_load_adapter_extension
|
126
|
+
# TODO: can we fix this shit in dm-mysql-adapter?
|
127
|
+
name = options[:adapter] || options['adapter']
|
128
|
+
# TODO: can we fix this adapter name in dm-sqlite-adapter?
|
129
|
+
adapter = name.sub(/\Asqlite3\Z/, 'sqlite')
|
130
|
+
|
131
|
+
require "dm-is-reflective/adapters/#{adapter}_adapter"
|
132
|
+
class_name = "#{Inflector.camelize(adapter)}Adapter"
|
133
|
+
Adapters.const_get(class_name).__send__(:include,
|
134
|
+
DmIsReflective.const_get(class_name))
|
135
|
+
end
|
136
|
+
end
|