dm-is-reflective 1.2.0 → 1.3.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 +4 -4
- data/CHANGES.md +9 -0
- data/dm-is-reflective.gemspec +2 -2
- data/lib/dm-is-reflective/adapters/data_objects_adapter.rb +2 -2
- data/lib/dm-is-reflective/adapters/mysql_adapter.rb +55 -16
- data/lib/dm-is-reflective/adapters/postgres_adapter.rb +48 -18
- data/lib/dm-is-reflective/adapters/sqlite_adapter.rb +50 -5
- data/lib/dm-is-reflective/reflective.rb +23 -9
- data/lib/dm-is-reflective/test.rb +73 -38
- data/lib/dm-is-reflective/version.rb +1 -1
- data/test/test_mysql.rb +1 -0
- data/test/test_postgres.rb +1 -0
- data/test/test_sqlite.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e05d37577ac7449933ee4680893d496c6ca138f
|
4
|
+
data.tar.gz: ff50451f50e9b1094db71272cbda92bb7476015a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb614bb45b425c7d5cbdbeb9cbaa8b8acb34ff4492af861c277cdfb60c116ec5560504dd10402dbb492dfa7f5adbc441588f40e0bd3fd59fef29e7535c47d858
|
7
|
+
data.tar.gz: 9bc150a2c0da4b77af03cca23f2f7c8148d7196689e714c4e8544e6fb38d506c2257dc5f5b25fca74b620e20893c4192eadbc8d2430f1f40ab0f2f8ecccbf5bd
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## dm-is-reflective 1.3.0, 2013-05-20
|
4
|
+
|
5
|
+
* Warn instead of raising a TypeError if a datatype cannot be found.
|
6
|
+
We fallback to use String.
|
7
|
+
* Now it works for multiple composite keys.
|
8
|
+
* If there's no key defined, it would pick the first unique index as the key.
|
9
|
+
* If a field name is conflicted, it would try to resolve it by appending a
|
10
|
+
underscore to the field name.
|
11
|
+
|
3
12
|
## dm-is-reflective 1.2.0, 2013-05-14
|
4
13
|
|
5
14
|
* We got a bunch of internal renaming.
|
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.
|
5
|
+
s.version = "1.3.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-05-
|
9
|
+
s.date = "2013-05-20"
|
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.executables = ["dm-is-reflective"]
|
@@ -114,12 +114,12 @@ module DmIsReflective::DataObjectsAdapter
|
|
114
114
|
model.storage_names[:default] = storage
|
115
115
|
scope.const_set(Inflector.classify(storage), model)
|
116
116
|
model.__send__(:reflect, /.*/)
|
117
|
-
model.finalize if model.respond_to?(:finalize)
|
118
117
|
model
|
119
118
|
end
|
120
119
|
|
121
120
|
def reflective_lookup_primitive primitive
|
122
|
-
|
121
|
+
warn "#{primitive} not found for #{self.class}: #{caller.inspect}"
|
122
|
+
String # falling back to the universal interface
|
123
123
|
end
|
124
124
|
|
125
125
|
def reflective_auto_load_adapter_extension
|
@@ -9,18 +9,50 @@ module DmIsReflective::MysqlAdapter
|
|
9
9
|
private
|
10
10
|
# construct needed table metadata
|
11
11
|
def reflective_query_storage storage
|
12
|
-
|
13
|
-
SELECT column_name,
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
sql_indices = <<-SQL
|
13
|
+
SELECT column_name, index_name, non_unique
|
14
|
+
FROM `information_schema`.`statistics`
|
15
|
+
WHERE table_schema = ? AND table_name = ?
|
16
|
+
SQL
|
17
|
+
|
18
|
+
sql_columns = <<-SQL
|
19
|
+
SELECT column_name, column_key, column_default, is_nullable,
|
20
|
+
data_type, character_maximum_length, extra, table_name
|
21
|
+
FROM `information_schema`.`columns`
|
22
|
+
WHERE table_schema = ? AND table_name = ?
|
17
23
|
SQL
|
18
24
|
|
19
25
|
# TODO: can we fix this shit in dm-mysql-adapter?
|
20
|
-
path = options[:path] || options['path'] ||
|
21
|
-
|
26
|
+
path = (options[:path] || options['path'] ||
|
27
|
+
options[:database] || options['database']).sub('/', '')
|
28
|
+
|
29
|
+
indices =
|
30
|
+
select(Ext::String.compress_lines(sql_indices), path, storage).
|
31
|
+
group_by(&:column_name)
|
22
32
|
|
23
|
-
select(Ext::String.compress_lines(
|
33
|
+
select(Ext::String.compress_lines(sql_columns), path, storage).
|
34
|
+
map do |column|
|
35
|
+
if idx = indices[column.column_name]
|
36
|
+
idx_uni, idx_com = idx.partition{ |i| i.non_unique == 0 }.map{ |i|
|
37
|
+
if i.empty?
|
38
|
+
nil
|
39
|
+
elsif i.size == 1
|
40
|
+
i.first.index_name.to_sym
|
41
|
+
else
|
42
|
+
i.map{ |ii| ii.index_name.to_sym }
|
43
|
+
end
|
44
|
+
}
|
45
|
+
else
|
46
|
+
idx_uni, idx_com = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
column.instance_eval <<-RUBY
|
50
|
+
def unique_index; #{idx_uni.inspect}; end
|
51
|
+
def index ; #{idx_com.inspect}; end
|
52
|
+
RUBY
|
53
|
+
|
54
|
+
column
|
55
|
+
end
|
24
56
|
end
|
25
57
|
|
26
58
|
def reflective_field_name field
|
@@ -32,17 +64,24 @@ module DmIsReflective::MysqlAdapter
|
|
32
64
|
end
|
33
65
|
|
34
66
|
def reflective_attributes field, attrs = {}
|
35
|
-
|
36
|
-
|
67
|
+
attrs[:serial] = true if field.extra == 'auto_increment'
|
68
|
+
|
69
|
+
if field.column_key == 'PRI'
|
70
|
+
attrs[:key] = true
|
71
|
+
attrs[:unique_index] = :"#{field.table_name}_pkey"
|
72
|
+
else
|
73
|
+
attrs[:unique_index] = field.unique_index if field.unique_index
|
74
|
+
attrs[ :index] = field. index if field. index
|
75
|
+
end
|
37
76
|
|
38
|
-
|
39
|
-
|
40
|
-
|
77
|
+
attrs[:allow_nil] = field.is_nullable == 'YES'
|
78
|
+
attrs[:default] = field.column_default if
|
79
|
+
field.column_default
|
41
80
|
|
42
|
-
|
43
|
-
|
81
|
+
attrs[:length] = field.character_maximum_length if
|
82
|
+
field.character_maximum_length
|
44
83
|
|
45
|
-
|
84
|
+
attrs
|
46
85
|
end
|
47
86
|
|
48
87
|
def reflective_lookup_primitive primitive
|
@@ -13,28 +13,53 @@ module DmIsReflective::PostgresAdapter
|
|
13
13
|
|
14
14
|
private
|
15
15
|
def reflective_query_storage storage
|
16
|
-
|
17
|
-
SELECT
|
18
|
-
|
16
|
+
sql_indices = <<-SQL
|
17
|
+
SELECT a.attname, i.relname, ix.indisprimary, ix.indisunique
|
18
|
+
FROM pg_class t, pg_class i, pg_index ix, pg_attribute a
|
19
|
+
WHERE t.oid = ix.indrelid
|
20
|
+
AND i.oid = ix.indexrelid
|
21
|
+
AND a.attrelid = t.oid
|
22
|
+
AND a.attnum = ANY(ix.indkey)
|
23
|
+
AND t.relkind = 'r'
|
24
|
+
AND t.relname = ?
|
19
25
|
SQL
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
sql = <<-SQL
|
27
|
+
sql_columns = <<-SQL
|
24
28
|
SELECT column_name, column_default, is_nullable,
|
25
29
|
character_maximum_length, udt_name
|
26
|
-
FROM
|
27
|
-
WHERE
|
30
|
+
FROM "information_schema"."columns"
|
31
|
+
WHERE table_schema = current_schema() AND table_name = ?
|
28
32
|
SQL
|
29
33
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
indices =
|
35
|
+
select(Ext::String.compress_lines(sql_indices), storage).
|
36
|
+
group_by(&:attname)
|
37
|
+
|
38
|
+
select(Ext::String.compress_lines(sql_columns), storage).map do |column|
|
39
|
+
if idx = indices[column.column_name]
|
40
|
+
is_key = !!idx.find{ |i| i.indisprimary }
|
41
|
+
idx_uni, idx_com = idx.partition{ |i| i.indisunique }.map{ |i|
|
42
|
+
if i.empty?
|
43
|
+
nil
|
44
|
+
elsif i.size == 1
|
45
|
+
i.first.relname.to_sym
|
46
|
+
else
|
47
|
+
i.map{ |ii| ii.relname.to_sym }
|
48
|
+
end
|
49
|
+
}
|
50
|
+
else
|
51
|
+
is_key = false
|
52
|
+
idx_uni, idx_com = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
column.instance_eval <<-RUBY
|
56
|
+
def key? ; #{is_key} ; end
|
57
|
+
def unique_index; #{idx_uni.inspect}; end
|
58
|
+
def index ; #{idx_com.inspect}; end
|
35
59
|
RUBY
|
36
|
-
|
37
|
-
|
60
|
+
|
61
|
+
column
|
62
|
+
end
|
38
63
|
end
|
39
64
|
|
40
65
|
def reflective_field_name field
|
@@ -47,11 +72,16 @@ module DmIsReflective::PostgresAdapter
|
|
47
72
|
|
48
73
|
def reflective_attributes field, attrs = {}
|
49
74
|
# strip data type
|
50
|
-
field.column_default
|
51
|
-
field.column_default
|
75
|
+
if field.column_default
|
76
|
+
field.column_default.gsub!(/(.*?)::[\w\s]*/, '\1')
|
77
|
+
end
|
52
78
|
|
53
79
|
attrs[:serial] = true if field.column_default =~ /nextval\('\w+'\)/
|
54
|
-
attrs[:key]
|
80
|
+
attrs[:key] = true if field.key?
|
81
|
+
|
82
|
+
attrs[:unique_index] = field.unique_index if field.unique_index
|
83
|
+
attrs[ :index] = field. index if field. index
|
84
|
+
|
55
85
|
attrs[:allow_nil] = field.is_nullable == 'YES'
|
56
86
|
# strip string quotation
|
57
87
|
attrs[:default] = field.column_default.gsub(/^'(.*?)'$/, '\1') if
|
@@ -4,8 +4,7 @@ module DmIsReflective::SqliteAdapter
|
|
4
4
|
|
5
5
|
def storages
|
6
6
|
sql = <<-SQL
|
7
|
-
SELECT name
|
8
|
-
FROM sqlite_master
|
7
|
+
SELECT name FROM sqlite_master
|
9
8
|
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
|
10
9
|
SQL
|
11
10
|
|
@@ -14,7 +13,48 @@ module DmIsReflective::SqliteAdapter
|
|
14
13
|
|
15
14
|
private
|
16
15
|
def reflective_query_storage storage
|
17
|
-
|
16
|
+
sql_indices = <<-SQL
|
17
|
+
SELECT name, sql FROM sqlite_master
|
18
|
+
WHERE type = 'index' AND tbl_name = ?
|
19
|
+
SQL
|
20
|
+
|
21
|
+
indices = select(sql_indices, storage).inject({}){ |r, field|
|
22
|
+
columns = field.sql[/\(.+\)/].scan(/\w+/)
|
23
|
+
uniqueness = !!field.sql[/CREATE UNIQUE INDEX/]
|
24
|
+
|
25
|
+
columns.each{ |c|
|
26
|
+
type = if uniqueness then :unique_index else :index end
|
27
|
+
r[c] ||= {:unique_index => [], :index => []}
|
28
|
+
r[c][type] << field.name
|
29
|
+
}
|
30
|
+
|
31
|
+
r
|
32
|
+
}
|
33
|
+
|
34
|
+
select('PRAGMA table_info(?)', storage).map{ |field|
|
35
|
+
if idx = indices[field.name]
|
36
|
+
idx_uni, idx_com = [:unique_index, :index].map{ |type|
|
37
|
+
i = idx[type]
|
38
|
+
if i.empty?
|
39
|
+
nil
|
40
|
+
elsif i.size == 1
|
41
|
+
i.first.to_sym
|
42
|
+
else
|
43
|
+
i.map(&:to_sym)
|
44
|
+
end
|
45
|
+
}
|
46
|
+
else
|
47
|
+
idx_uni, idx_com = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
field.instance_eval <<-RUBY
|
51
|
+
def table_name ; '#{storage}' ; end
|
52
|
+
def index ; #{idx_com.inspect}; end
|
53
|
+
def unique_index; #{idx_uni.inspect}; end
|
54
|
+
RUBY
|
55
|
+
|
56
|
+
field
|
57
|
+
}
|
18
58
|
end
|
19
59
|
|
20
60
|
def reflective_field_name field
|
@@ -27,9 +67,14 @@ module DmIsReflective::SqliteAdapter
|
|
27
67
|
|
28
68
|
def reflective_attributes field, attrs = {}
|
29
69
|
if field.pk != 0
|
30
|
-
attrs[:key]
|
31
|
-
attrs[:serial]
|
70
|
+
attrs[:key] = true
|
71
|
+
attrs[:serial] = true
|
72
|
+
attrs[:unique_index] = :"#{field.table_name}_pkey"
|
32
73
|
end
|
74
|
+
|
75
|
+
attrs[:unique_index] = field.unique_index if field.unique_index
|
76
|
+
attrs[ :index] = field. index if field. index
|
77
|
+
|
33
78
|
attrs[:allow_nil] = field.notnull == 0
|
34
79
|
attrs[:default] = field.dflt_value[1..-2] if field.dflt_value
|
35
80
|
|
@@ -55,27 +55,41 @@ module DmIsReflective
|
|
55
55
|
|
56
56
|
reflected = targets.each{ |target|
|
57
57
|
case target
|
58
|
-
|
59
|
-
|
58
|
+
when Regexp;
|
59
|
+
break name if name.to_s =~ target
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
when Symbol, String;
|
62
|
+
break name if name == target.to_sym
|
63
63
|
|
64
|
-
|
65
|
-
|
64
|
+
when Class;
|
65
|
+
break name if type == target
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
else
|
68
|
+
raise ArgumentError.new("invalid argument: #{target.inspect}")
|
69
69
|
end
|
70
70
|
}
|
71
71
|
|
72
|
-
|
72
|
+
reflect_property(reflected, type, attrs) if
|
73
|
+
reflected.kind_of?(Symbol)
|
73
74
|
}.compact
|
74
75
|
|
76
|
+
if key.empty? && k = properties.find{ |p| p.unique_index }
|
77
|
+
property k.name, k.primitive, :key => true
|
78
|
+
end
|
79
|
+
|
75
80
|
finalize if respond_to?(:finalize)
|
76
81
|
result
|
77
82
|
end
|
78
83
|
|
84
|
+
def reflect_property reflected, type, attrs
|
85
|
+
property reflected, type, attrs
|
86
|
+
rescue ArgumentError => e
|
87
|
+
if e.message =~ /cannot be used as a property name/
|
88
|
+
reflect_property "#{reflected}_", type,
|
89
|
+
{:field => reflected.to_s}.merge(attrs)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
79
93
|
def to_source scope=nil
|
80
94
|
<<-RUBY
|
81
95
|
class #{scope}::#{name} < #{superclass}
|
@@ -7,6 +7,32 @@ require 'dm-migrations'
|
|
7
7
|
require 'dm-is-reflective'
|
8
8
|
|
9
9
|
module Abstract
|
10
|
+
class Cat
|
11
|
+
include DataMapper::Resource
|
12
|
+
property :id, Serial
|
13
|
+
|
14
|
+
belongs_to :user
|
15
|
+
belongs_to :super_user
|
16
|
+
|
17
|
+
property :user_id , Integer,
|
18
|
+
:unique_index => [:usu, :u]
|
19
|
+
property :super_user_id, Integer,
|
20
|
+
:unique_index => [:usu],
|
21
|
+
:index => [:su]
|
22
|
+
end
|
23
|
+
|
24
|
+
class Comment
|
25
|
+
include DataMapper::Resource
|
26
|
+
belongs_to :user, :required => false
|
27
|
+
|
28
|
+
property :id, Serial
|
29
|
+
property :title, String, :length => 50, :default => 'default title',
|
30
|
+
:allow_nil => false
|
31
|
+
property :body, Text
|
32
|
+
|
33
|
+
is :reflective
|
34
|
+
end
|
35
|
+
|
10
36
|
class User
|
11
37
|
include DataMapper::Resource
|
12
38
|
has n, :comments
|
@@ -27,19 +53,8 @@ module Abstract
|
|
27
53
|
is :reflective
|
28
54
|
end
|
29
55
|
|
30
|
-
|
31
|
-
|
32
|
-
belongs_to :user, :required => false
|
33
|
-
|
34
|
-
property :id, Serial
|
35
|
-
property :title, String, :length => 50, :default => 'default title',
|
36
|
-
:allow_nil => false
|
37
|
-
property :body, Text
|
38
|
-
|
39
|
-
is :reflective
|
40
|
-
end
|
41
|
-
|
42
|
-
Tables = ['abstract_comments', 'abstract_super_users', 'abstract_users']
|
56
|
+
Tables = %w[abstract_cats abstract_comments
|
57
|
+
abstract_super_users abstract_users]
|
43
58
|
|
44
59
|
AttrCommon = {:allow_nil => true}
|
45
60
|
AttrCommonPK = {:serial => true, :key => true, :allow_nil => false}
|
@@ -54,40 +69,58 @@ end
|
|
54
69
|
include Abstract
|
55
70
|
|
56
71
|
shared :reflective do
|
72
|
+
def cat_fields
|
73
|
+
@cat_fields ||=
|
74
|
+
[[:id, DataMapper::Property::Serial,
|
75
|
+
{:unique_index => :abstract_cats_pkey}.merge(AttrCommonPK)],
|
76
|
+
[:super_user_id, Integer,
|
77
|
+
{:unique_index => :unique_abstract_cats_usu,
|
78
|
+
:index => :index_abstract_cats_su }.merge(AttrCommon)],
|
79
|
+
[:user_id , Integer,
|
80
|
+
{:unique_index => [:unique_abstract_cats_usu,
|
81
|
+
:unique_abstract_cats_u]}.merge(AttrCommon)]]
|
82
|
+
end
|
83
|
+
|
84
|
+
def comment_fields
|
85
|
+
@comment_fields ||= begin
|
86
|
+
[[:body , DataMapper::Property::Text , AttrText],
|
87
|
+
[:id , DataMapper::Property::Serial,
|
88
|
+
{:unique_index => :abstract_comments_pkey}.merge(AttrCommonPK)],
|
89
|
+
|
90
|
+
[:title , String ,
|
91
|
+
{:length => 50, :default => 'default title', :allow_nil => false}],
|
92
|
+
|
93
|
+
[:user_id, Integer ,
|
94
|
+
{:index => :index_abstract_comments_user}.merge(AttrCommon)]]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
57
98
|
def user_fields
|
99
|
+
@user_fields ||=
|
58
100
|
[[:created_at, DateTime, AttrCommon],
|
59
|
-
[:id, DataMapper::Property::Serial,
|
101
|
+
[:id, DataMapper::Property::Serial,
|
102
|
+
{:unique_index => :abstract_users_pkey}.merge(AttrCommonPK)],
|
60
103
|
[:login, String, {:length => 70}.merge(AttrCommon)],
|
61
104
|
[:sig, DataMapper::Property::Text, AttrText]]
|
62
105
|
end
|
63
106
|
|
64
|
-
def comment_fields
|
65
|
-
[[:body, DataMapper::Property::Text, AttrText],
|
66
|
-
[:id, DataMapper::Property::Serial, AttrCommonPK],
|
67
|
-
[:title, String, {:length => 50, :default => 'default title',
|
68
|
-
:allow_nil => false}],
|
69
|
-
[:user_id, Integer, AttrCommon]]
|
70
|
-
end
|
71
|
-
|
72
|
-
# there's differences between adapters
|
73
107
|
def super_user_fields
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
[:id, DataMapper::Property::Serial, AttrCommonPK]]
|
108
|
+
@super_user_fields ||= begin
|
109
|
+
type = case DataMapper.repository.adapter.class.name
|
110
|
+
when 'DataMapper::Adapters::MysqlAdapter'
|
111
|
+
Integer
|
112
|
+
else
|
113
|
+
DataMapper::Property::Boolean
|
114
|
+
end
|
115
|
+
[[:bool, type, AttrCommon],
|
116
|
+
[:id , DataMapper::Property::Serial,
|
117
|
+
{:unique_index => :abstract_super_users_pkey}.merge(AttrCommonPK)]]
|
85
118
|
end
|
86
119
|
end
|
87
120
|
|
88
121
|
before do
|
89
122
|
@dm = setup_data_mapper
|
90
|
-
[
|
123
|
+
[Cat, Comment, User, SuperUser].each(&:auto_migrate!)
|
91
124
|
end
|
92
125
|
|
93
126
|
def sort_fields fields
|
@@ -167,8 +200,9 @@ shared :reflective do
|
|
167
200
|
key, value = i
|
168
201
|
r[key] = value.sort_by{ |v| v.first.to_s }
|
169
202
|
r
|
170
|
-
}.should.eq('
|
171
|
-
'abstract_comments' =>
|
203
|
+
}.should.eq('abstract_cats' => cat_fields,
|
204
|
+
'abstract_comments' => comment_fields,
|
205
|
+
'abstract_users' => user_fields,
|
172
206
|
'abstract_super_users' => super_user_fields)
|
173
207
|
end
|
174
208
|
|
@@ -215,7 +249,8 @@ shared :reflective do
|
|
215
249
|
should 'auto_genclasses' do
|
216
250
|
scope = new_scope
|
217
251
|
@dm.auto_genclass!(:scope => scope).map(&:to_s).sort.should.eq \
|
218
|
-
["#{scope}::
|
252
|
+
["#{scope}::AbstractCat" ,
|
253
|
+
"#{scope}::AbstractComment" ,
|
219
254
|
"#{scope}::AbstractSuperUser",
|
220
255
|
"#{scope}::AbstractUser"]
|
221
256
|
|
data/test/test_mysql.rb
CHANGED
data/test/test_postgres.rb
CHANGED
data/test/test_sqlite.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-is-reflective
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lin Jen-Shin (godfat)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dm-core
|