dm-is-reflective 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e05d37577ac7449933ee4680893d496c6ca138f
4
- data.tar.gz: ff50451f50e9b1094db71272cbda92bb7476015a
3
+ metadata.gz: e0cf6d64d700dd5f9892573cc43a1d19eb3ba2cd
4
+ data.tar.gz: 7c7647fd2e0a7c917aaf4b035432cff3849ad828
5
5
  SHA512:
6
- metadata.gz: eb614bb45b425c7d5cbdbeb9cbaa8b8acb34ff4492af861c277cdfb60c116ec5560504dd10402dbb492dfa7f5adbc441588f40e0bd3fd59fef29e7535c47d858
7
- data.tar.gz: 9bc150a2c0da4b77af03cca23f2f7c8148d7196689e714c4e8544e6fb38d506c2257dc5f5b25fca74b620e20893c4192eadbc8d2430f1f40ab0f2f8ecccbf5bd
6
+ metadata.gz: f2551113619f6540170864bcb217550037d70e5f4887812c88501b8aa302174080b7244817596e47d45e7d9826b0d152a39cc040d352a2d7803795b33e5946b0
7
+ data.tar.gz: eb33bdb42e9c47d686a7f8cd99a8848f99260fa82053d751e070855de838f045aa4b146b5919fa469a77b9b8b3b71cfd1f7b9cbb59b658d37c2e6702e64c10f6
data/CHANGES.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGES
2
2
 
3
+ ## dm-is-reflective 1.3.1, 2013-05-22
4
+
5
+ * Introduce `indices` method which would return all indices in the storage.
6
+
3
7
  ## dm-is-reflective 1.3.0, 2013-05-20
4
8
 
5
9
  * Warn instead of raising a TypeError if a datatype cannot be found.
data/README.md CHANGED
@@ -80,6 +80,9 @@ end
80
80
  dm.storages
81
81
  # => ['users']
82
82
 
83
+ # show all indices
84
+ dm.indices('users') # [:id, {:unique_index => :users_pkey}]
85
+
83
86
  # there's no guarantee of the order in fields array
84
87
  User.fields
85
88
  # => [[:created_at, DateTime, {:required => false}],
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "dm-is-reflective"
5
- s.version = "1.3.0"
5
+ s.version = "1.3.1"
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-20"
9
+ s.date = "2013-05-22"
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"]
@@ -10,6 +10,12 @@ module DmIsReflective::DataObjectsAdapter
10
10
  storages # call the overrided method
11
11
  end
12
12
 
13
+ # returns all indices in the storage.
14
+ def indices storage
15
+ reflective_auto_load_adapter_extension
16
+ indices(storage) # call the overrided method
17
+ end
18
+
13
19
  # returns all fields, with format [[name, type, attrs]]
14
20
  # e.g.
15
21
  # [[:created_at, DateTime, {:required => false}],
@@ -133,4 +139,12 @@ module DmIsReflective::DataObjectsAdapter
133
139
  Adapters.const_get(class_name).__send__(:include,
134
140
  DmIsReflective.const_get(class_name))
135
141
  end
142
+
143
+ def reflective_indices_hash key, idx_uni, idx_com
144
+ h = {}
145
+ h[:key] = key if key
146
+ h[:unique_index] = idx_uni if idx_uni
147
+ h[ :index] = idx_com if idx_com
148
+ h
149
+ end
136
150
  end
@@ -6,53 +6,51 @@ module DmIsReflective::MysqlAdapter
6
6
  select('SHOW TABLES')
7
7
  end
8
8
 
9
- private
10
- # construct needed table metadata
11
- def reflective_query_storage storage
12
- sql_indices = <<-SQL
9
+ def indices storage
10
+ sql = <<-SQL
13
11
  SELECT column_name, index_name, non_unique
14
12
  FROM `information_schema`.`statistics`
15
13
  WHERE table_schema = ? AND table_name = ?
16
14
  SQL
17
15
 
18
- sql_columns = <<-SQL
16
+ select(Ext::String.compress_lines(sql),
17
+ reflective_table_schema, storage).group_by(&:column_name).
18
+ inject({}) do |r, (column, idxs)|
19
+ primary = idxs.find{ |i| i.index_name == 'PRIMARY' }
20
+ primary.index_name = :"#{storage}_pkey" if primary
21
+ key = !!primary
22
+ idx_uni, idx_com = idxs.partition{ |i| i.non_unique == 0 }.map{ |i|
23
+ if i.empty?
24
+ nil
25
+ elsif i.size == 1
26
+ i.first.index_name.to_sym
27
+ else
28
+ i.map{ |ii| ii.index_name.to_sym }
29
+ end
30
+ }
31
+
32
+ r[column.to_sym] = reflective_indices_hash(key, idx_uni, idx_com)
33
+ r
34
+ end
35
+ end
36
+
37
+ private
38
+ # construct needed table metadata
39
+ def reflective_query_storage storage
40
+ sql = <<-SQL
19
41
  SELECT column_name, column_key, column_default, is_nullable,
20
42
  data_type, character_maximum_length, extra, table_name
21
43
  FROM `information_schema`.`columns`
22
44
  WHERE table_schema = ? AND table_name = ?
23
45
  SQL
24
46
 
25
- # TODO: can we fix this shit in dm-mysql-adapter?
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)
32
-
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
47
+ idxs = indices(storage)
53
48
 
54
- column
55
- end
49
+ select(Ext::String.compress_lines(sql),
50
+ reflective_table_schema, storage).map do |f|
51
+ f.define_singleton_method(:indices){ idxs[f.column_name.to_sym] }
52
+ f
53
+ end
56
54
  end
57
55
 
58
56
  def reflective_field_name field
@@ -63,15 +61,14 @@ module DmIsReflective::MysqlAdapter
63
61
  field.data_type
64
62
  end
65
63
 
66
- def reflective_attributes field, attrs = {}
64
+ def reflective_attributes field, attrs={}
65
+ attrs.merge!(field.indices) if field.indices
66
+
67
67
  attrs[:serial] = true if field.extra == 'auto_increment'
68
68
 
69
69
  if field.column_key == 'PRI'
70
70
  attrs[:key] = true
71
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
72
  end
76
73
 
77
74
  attrs[:allow_nil] = field.is_nullable == 'YES'
@@ -99,4 +96,10 @@ module DmIsReflective::MysqlAdapter
99
96
  when /\w*TEXT/ ; Property::Text
100
97
  end || super(primitive)
101
98
  end
99
+
100
+ def reflective_table_schema
101
+ # TODO: can we fix this shit in dm-mysql-adapter?
102
+ (options[:path] || options['path'] ||
103
+ options[:database] || options['database']).sub('/', '')
104
+ end
102
105
  end
@@ -11,9 +11,8 @@ module DmIsReflective::PostgresAdapter
11
11
  select(Ext::String.compress_lines(sql))
12
12
  end
13
13
 
14
- private
15
- def reflective_query_storage storage
16
- sql_indices = <<-SQL
14
+ def indices storage
15
+ sql = <<-SQL
17
16
  SELECT a.attname, i.relname, ix.indisprimary, ix.indisunique
18
17
  FROM pg_class t, pg_class i, pg_index ix, pg_attribute a
19
18
  WHERE t.oid = ix.indrelid
@@ -24,21 +23,10 @@ module DmIsReflective::PostgresAdapter
24
23
  AND t.relname = ?
25
24
  SQL
26
25
 
27
- sql_columns = <<-SQL
28
- SELECT column_name, column_default, is_nullable,
29
- character_maximum_length, udt_name
30
- FROM "information_schema"."columns"
31
- WHERE table_schema = current_schema() AND table_name = ?
32
- SQL
33
-
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|
26
+ select(Ext::String.compress_lines(sql), storage).group_by(&:attname).
27
+ inject({}) do |r, (column, idxs)|
28
+ key = !!idxs.find(&:indisprimary)
29
+ idx_uni, idx_com = idxs.partition(&:indisunique).map{ |i|
42
30
  if i.empty?
43
31
  nil
44
32
  elsif i.size == 1
@@ -47,18 +35,26 @@ module DmIsReflective::PostgresAdapter
47
35
  i.map{ |ii| ii.relname.to_sym }
48
36
  end
49
37
  }
50
- else
51
- is_key = false
52
- idx_uni, idx_com = nil
38
+
39
+ r[column.to_sym] = reflective_indices_hash(key, idx_uni, idx_com)
40
+ r
53
41
  end
42
+ end
54
43
 
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
59
- RUBY
44
+ private
45
+ def reflective_query_storage storage
46
+ sql = <<-SQL
47
+ SELECT column_name, column_default, is_nullable,
48
+ character_maximum_length, udt_name
49
+ FROM "information_schema"."columns"
50
+ WHERE table_schema = current_schema() AND table_name = ?
51
+ SQL
52
+
53
+ idxs = indices(storage)
60
54
 
61
- column
55
+ select(Ext::String.compress_lines(sql), storage).map do |f|
56
+ f.define_singleton_method(:indices){ idxs[f.column_name.to_sym] }
57
+ f
62
58
  end
63
59
  end
64
60
 
@@ -70,18 +66,15 @@ module DmIsReflective::PostgresAdapter
70
66
  field.udt_name
71
67
  end
72
68
 
73
- def reflective_attributes field, attrs = {}
69
+ def reflective_attributes field, attrs={}
74
70
  # strip data type
75
71
  if field.column_default
76
72
  field.column_default.gsub!(/(.*?)::[\w\s]*/, '\1')
77
73
  end
78
74
 
79
- attrs[:serial] = true if field.column_default =~ /nextval\('\w+'\)/
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
75
+ attrs.merge!(field.indices) if field.indices
84
76
 
77
+ attrs[:serial] = true if field.column_default =~ /nextval\('\w+'\)/
85
78
  attrs[:allow_nil] = field.is_nullable == 'YES'
86
79
  # strip string quotation
87
80
  attrs[:default] = field.column_default.gsub(/^'(.*?)'$/, '\1') if
@@ -11,49 +11,46 @@ module DmIsReflective::SqliteAdapter
11
11
  select(Ext::String.compress_lines(sql))
12
12
  end
13
13
 
14
- private
15
- def reflective_query_storage storage
16
- sql_indices = <<-SQL
14
+ def indices storage
15
+ sql = <<-SQL
17
16
  SELECT name, sql FROM sqlite_master
18
17
  WHERE type = 'index' AND tbl_name = ?
19
18
  SQL
20
19
 
21
- indices = select(sql_indices, storage).inject({}){ |r, field|
22
- columns = field.sql[/\(.+\)/].scan(/\w+/)
23
- uniqueness = !!field.sql[/CREATE UNIQUE INDEX/]
20
+ select(Ext::String.compress_lines(sql), storage).inject({}){ |r, idx|
21
+ columns = idx.sql[/\(.+\)/].scan(/\w+/)
22
+ uniqueness = !!idx.sql[/CREATE UNIQUE INDEX/]
24
23
 
25
24
  columns.each{ |c|
26
25
  type = if uniqueness then :unique_index else :index end
27
26
  r[c] ||= {:unique_index => [], :index => []}
28
- r[c][type] << field.name
27
+ r[c][type] << idx.name.to_sym
29
28
  }
30
29
 
30
+ r
31
+ }.inject({}){ |r, (column, idxs)|
32
+ idx_uni, idx_com = [:unique_index, :index].map{ |type|
33
+ i = idxs[type]
34
+ if i.empty?
35
+ nil
36
+ elsif i.size == 1
37
+ i.first.to_sym
38
+ else
39
+ i.map(&:to_sym)
40
+ end
41
+ }
42
+ r[column.to_sym] = reflective_indices_hash(false, idx_uni, idx_com)
31
43
  r
32
44
  }
45
+ end
33
46
 
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
47
+ private
48
+ def reflective_query_storage storage
49
+ idxs = indices(storage)
50
+ select('PRAGMA table_info(?)', storage).map{ |f|
51
+ f.define_singleton_method(:storage){ storage }
52
+ f.define_singleton_method(:indices){ idxs[f.name.to_sym] }
53
+ f
57
54
  }
58
55
  end
59
56
 
@@ -65,16 +62,15 @@ module DmIsReflective::SqliteAdapter
65
62
  field.type.gsub(/\(\d+\)/, '')
66
63
  end
67
64
 
68
- def reflective_attributes field, attrs = {}
65
+ def reflective_attributes field, attrs={}
66
+ attrs.merge!(field.indices) if field.indices
67
+
69
68
  if field.pk != 0
70
69
  attrs[:key] = true
71
70
  attrs[:serial] = true
72
- attrs[:unique_index] = :"#{field.table_name}_pkey"
71
+ attrs[:unique_index] = :"#{field.storage}_pkey"
73
72
  end
74
73
 
75
- attrs[:unique_index] = field.unique_index if field.unique_index
76
- attrs[ :index] = field. index if field. index
77
-
78
74
  attrs[:allow_nil] = field.notnull == 0
79
75
  attrs[:default] = field.dflt_value[1..-2] if field.dflt_value
80
76
 
@@ -69,6 +69,23 @@ end
69
69
  include Abstract
70
70
 
71
71
  shared :reflective do
72
+ def cat_indices
73
+ @cat_indices ||= begin
74
+ id = case DataMapper.repository.adapter.class.name
75
+ when 'DataMapper::Adapters::SqliteAdapter'
76
+ nil
77
+ else
78
+ [:id, {:unique_index => :abstract_cats_pkey, :key => true}]
79
+ end
80
+ [id ,
81
+ [:super_user_id, {:unique_index => :unique_abstract_cats_usu ,
82
+ :index => :index_abstract_cats_su }] ,
83
+ [ :user_id, {:unique_index => [:unique_abstract_cats_usu ,
84
+ :unique_abstract_cats_u]}] ].
85
+ compact
86
+ end
87
+ end
88
+
72
89
  def cat_fields
73
90
  @cat_fields ||=
74
91
  [[:id, DataMapper::Property::Serial,
@@ -206,6 +223,10 @@ shared :reflective do
206
223
  'abstract_super_users' => super_user_fields)
207
224
  end
208
225
 
226
+ should 'indices' do
227
+ sort_fields(@dm.indices('abstract_cats')).should.eq cat_indices
228
+ end
229
+
209
230
  should 'reflect type' do
210
231
  model, local_dm = create_fake_model
211
232
  model.storage_names[:default] = 'abstract_comments'
@@ -1,4 +1,4 @@
1
1
 
2
2
  module DmIsReflective
3
- VERSION = '1.3.0'
3
+ VERSION = '1.3.1'
4
4
  end
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.3.0
4
+ version: 1.3.1
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-20 00:00:00.000000000 Z
11
+ date: 2013-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dm-core